Skip to content

Commit

Permalink
Add support for looking up webapp resources (both core and plugins)
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-beck committed Feb 5, 2019
1 parent 492bb16 commit a5b4e4f
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 10 deletions.
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
<url>https://wiki.jenkins.io/display/JENKINS/Localization+Support+Plugin</url>

<properties>
<jenkins.version>2.151-SNAPSHOT</jenkins.version>
<jenkins.version>2.164-SNAPSHOT</jenkins.version>
<jenkins-core.version>2.164-20190205.211051-1</jenkins-core.version>
<jenkins-war.version>2.164-20190205.211156-1</jenkins-war.version>
<java.level>8</java.level>
</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,14 @@ public static URL findResource(String resource, Class clazz) {
// fallback to default: Looking in the class context
return clazz.getResource(resource);
}

/**
* Look up a resource for a plugin.
*
* @param resource the resource to look up
* @param plugin the plugin
* @return resource for a plugin, or null if not found
*/
@CheckForNull
public abstract URL getPluginResource(@Nonnull String resource, @Nonnull PluginWrapper plugin);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.WebApp;
import org.kohsuke.stapler.interceptor.RequirePOST;
import org.kohsuke.stapler.jelly.JellyFacet;
import org.kohsuke.stapler.jelly.ResourceBundleFactory;

import java.io.IOException;
import java.lang.reflect.Method;

/**
* This admin monitor ensures that Stapler's JellyFacet uses this plugin's implementation.
Expand All @@ -51,8 +49,6 @@
@Restricted(NoExternalUse.class)
public class LocalizationMonitor extends AdministrativeMonitor {

// TODO extend with a check for the Metaclassloader.debugLoader

private PluginWrapper plugin;

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* The MIT License
*
* Copyright (c) 2019 CloudBees, Inc., Daniel Beck
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.jenkins.plugins.localization.support.stapler;

import hudson.Extension;
import hudson.ExtensionList;
import hudson.PluginWrapper;
import io.jenkins.plugins.localization.support.LocalizationContributor;
import jenkins.model.Jenkins;
import org.kohsuke.stapler.LocaleDrivenResourceProvider;

import javax.annotation.Nonnull;
import java.net.URL;
import java.util.logging.Logger;

@Extension
public class LocaleDrivenResourceProviderImpl extends LocaleDrivenResourceProvider {

@Override
public URL lookup(@Nonnull String path) {
PluginWrapper pluginWrapper = findPluginForResourceUrl(path);
if (pluginWrapper != null) {
path = path.substring(pluginWrapper.baseResourceURL.toString().length());
LOGGER.fine("Looking up localized file '" + path + "' from plugin '" + pluginWrapper + "'");
} else {
LOGGER.fine("Looking up localized file '" + path + "' from webapp");
}
for (LocalizationContributor contributor : ExtensionList.lookup(LocalizationContributor.class)) {
URL url;

if (pluginWrapper == null) {
url = contributor.getResource(path);
} else {
url = contributor.getPluginResource(path, pluginWrapper);
}
if (url != null) {
LOGGER.fine("Found localized file '" + path + "'");
return url;
}
}
LOGGER.fine("Failed to find localized file '" + path + "'");
return null;
}

private PluginWrapper findPluginForResourceUrl(String s) {
for (PluginWrapper wrapper : Jenkins.get().pluginManager.getPlugins()) {
if (s.startsWith(wrapper.baseResourceURL.toString())) {
return wrapper;
}
}
return null;
}

private static final Logger LOGGER = Logger.getLogger(LocaleDrivenResourceProviderImpl.class.getName());
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import jenkins.model.Jenkins;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.MetaClassLoader;
import org.kohsuke.stapler.WebApp;
import org.kohsuke.stapler.jelly.JellyFacet;

Expand All @@ -40,9 +39,5 @@ public static void initialize() {
// Override where the Jelly views look for resource bundles
JellyFacet facet = webApp.getFacet(JellyFacet.class);
facet.resourceBundleFactory = new ResourceBundleFactoryImpl();

// Provide a fallback source for resources
// TODO restrict to localization plugins only, or perhaps add a dedicated feature to Stapler for this
MetaClassLoader.debugLoader = new MetaClassLoader(Jenkins.get().pluginManager.uberClassLoader);
}
}

0 comments on commit a5b4e4f

Please sign in to comment.