JavaScipt and GWT based UI plugin support

Adds support for extending Gerrit's web UI using either pure
JavaScript or GWT compiled with a modified CrossSiteIframeLinker.

To add code to the web UI plugins should bind WebUiPlugin to either
GwtPlugin or JavaScriptPlugin in their plugin's Web-Module. This
tells the UI bootstrap code where to find additional JavaScript to
inject into the page before displaying content.

For a GWT based plugin:

  * com.google.gerrit.client.Plugin class should be extended,
  * inheritance from com.google.gerrit.Plugin should be added
    to gwt.xml,
  * subclass of client.Plugin should be set as entry point,
  * dependency from com.google.gerrit/gerrit-plugin-gwtui should
    be added to pom.xml,
  * webappDirectory option for gwt-maven-plugin should be
    set to ${project.build.directory}/classes/static

For JavaScript based plugins the source code should be put into
the static/ directory of the plugin's JAR file.

Currently there are no extension points for either JS or GWT plugins
to interact with. Some will be added in a future commit. With this
commit only simple modification of the UI is possible, for example
calling window.alert() or adding extra elements to page contents
based on the existing element ids.

Change-Id: I3558991ba4a1477d6cde64eb0a761a7e4c399ec3
Signed-off-by: Dariusz Luksza <dariusz@luksza.org>
This commit is contained in:
Dariusz Luksza 2012-10-10 11:10:09 +02:00 committed by Shawn O. Pearce
parent bc16fa2f3f
commit cd4fc1c239
21 changed files with 793 additions and 39 deletions

View File

@ -17,6 +17,8 @@ package com.google.gerrit.common.data;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
import java.util.List;
/** Data sent as part of the host page, to bootstrap the UI. */
public class HostPageData {
public Account account;
@ -24,6 +26,7 @@ public class HostPageData {
public String xsrfToken;
public GerritConfig config;
public Theme theme;
public List<String> plugins;
public static class Theme {
public String backgroundColor;

View File

@ -0,0 +1,33 @@
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.webui;
/** Configures a web UI plugin compiled using GWT. */
public class GwtPlugin extends WebUiPlugin {
private final String moduleName;
/**
* @param moduleName name of GWT module. The resource
* {@code static/$MODULE/$MODULE.nocache.js} will be used.
*/
public GwtPlugin(String moduleName) {
this.moduleName = moduleName;
}
@Override
public String getJavaScriptResourcePath() {
return String.format("static/%s/%s.nocache.js", moduleName, moduleName);
}
}

View File

@ -0,0 +1,33 @@
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.webui;
/** Configures a web UI plugin written using JavaScript. */
public class JavaScriptPlugin extends WebUiPlugin {
private final String fileName;
/**
* @param fileName of JavaScript source file under {@code static/}
* subdirectory within the plugin's JAR.
*/
public JavaScriptPlugin(String fileName) {
this.fileName = fileName;
}
@Override
public String getJavaScriptResourcePath() {
return "static/" + fileName;
}
}

View File

@ -0,0 +1,54 @@
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.webui;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.inject.Inject;
/**
* Specifies JavaScript to dynamically load into the web UI.
*
* @see GwtPlugin
* @see JavaScriptPlugin
*/
public abstract class WebUiPlugin {
public static final GwtPlugin gwt(String moduleName) {
return new GwtPlugin(moduleName);
}
public static final JavaScriptPlugin js(String scriptName) {
return new JavaScriptPlugin(scriptName);
}
private String pluginName;
/** @return installed name of the plugin that provides this UI feature. */
public final String getPluginName() {
return pluginName;
}
@Inject
void setPluginName(@PluginName String pluginName) {
this.pluginName = pluginName;
}
/** @return path to initialization script within the plugin's JAR. */
public abstract String getJavaScriptResourcePath();
@Override
public String toString() {
return getJavaScriptResourcePath();
}
}

View File

@ -42,9 +42,11 @@ import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
@ -68,9 +70,12 @@ import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwtexpui.clippy.client.CopyableLabel;
import com.google.gwtexpui.user.client.UserAgent;
import com.google.gwtexpui.user.client.ViewSite;
import com.google.gwtjsonrpc.client.CallbackHandle;
import com.google.gwtjsonrpc.client.JsonDefTarget;
import com.google.gwtjsonrpc.client.JsonUtil;
import com.google.gwtjsonrpc.client.XsrfManager;
import com.google.gwtjsonrpc.client.impl.ResultDeserializer;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtorm.client.KeyUtil;
import java.util.ArrayList;
@ -371,6 +376,7 @@ public class Gerrit implements EntryPoint {
final HostPageDataService hpd = GWT.create(HostPageDataService.class);
hpd.load(new GerritCallback<HostPageData>() {
@Override
public void onSuccess(final HostPageData result) {
Document.get().getElementById("gerrit_hostpagedata").removeFromParent();
myConfig = result.config;
@ -383,7 +389,7 @@ public class Gerrit implements EntryPoint {
myAccountDiffPref = result.accountDiffPref;
applyUserPreferences();
}
onModuleLoad2();
onModuleLoad2(result);
}
});
}
@ -465,7 +471,7 @@ public class Gerrit implements EntryPoint {
btmmenu.add(poweredBy);
}
private void onModuleLoad2() {
private void onModuleLoad2(HostPageData hpd) {
RESOURCES.gwt_override().ensureInjected();
RESOURCES.css().ensureInjected();
@ -543,6 +549,7 @@ public class Gerrit implements EntryPoint {
refreshMenuBar();
History.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(final ValueChangeEvent<String> event) {
display(event.getValue());
}
@ -558,7 +565,50 @@ public class Gerrit implements EntryPoint {
if (signInAnchor != null) {
signInAnchor.setHref(loginRedirect(token));
}
display(token);
loadPlugins(hpd, token);
}
private void loadPlugins(HostPageData hpd, final String token) {
if (hpd.plugins != null) {
for (final String url : hpd.plugins) {
ScriptInjector.fromUrl(url)
.setWindow(ScriptInjector.TOP_WINDOW)
.setCallback(new Callback<Void, Exception>() {
@Override
public void onSuccess(Void result) {
}
@Override
public void onFailure(Exception reason) {
ErrorDialog d = new ErrorDialog(reason);
d.setTitle(M.pluginFailed(url));
d.center();
}
}).inject();
}
}
CallbackHandle<Void> cb = new CallbackHandle<Void>(
new ResultDeserializer<Void>() {
@Override
public Void fromResult(JavaScriptObject responseObject) {
return null;
}
},
new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(Void result) {
display(token);
}
});
cb.install();
ScriptInjector.fromString(cb.getFunctionName() + "();")
.setWindow(ScriptInjector.TOP_WINDOW)
.inject();
}
public static void refreshMenuBar() {

View File

@ -22,7 +22,6 @@ public interface GerritMessages extends Messages {
String poweredBy(String version);
String noSuchAccountMessage(String who);
String noSuchGroupMessage(String who);
String branchCreationFailed(String branchName, String error);
@ -31,4 +30,6 @@ public interface GerritMessages extends Messages {
String branchCreationNotAllowedUnderRefnamePrefix(String refnamePrefix);
String branchAlreadyExists(String branchName);
String branchCreationConflict(String branchName, String existingBranchName);
String pluginFailed(String scriptPath);
}

View File

@ -3,7 +3,6 @@ windowTitle2 = {0} | {1} Code Review
poweredBy = Powered by <a href="http://code.google.com/p/gerrit/" target="_blank">Gerrit Code Review</a> ({0})
noSuchAccountMessage = {0} is not a registered user.
noSuchGroupMessage = Group {0} does not exist or is not visible to you.
branchCreationFailed = Creating branch {0} failed. Error: {1}
@ -12,3 +11,5 @@ invalidRevision = The revision {0} is not valid.
branchCreationNotAllowedUnderRefnamePrefix = Branch creation is not allowed under {0}.
branchAlreadyExists = A branch with the name {0} already exists.
branchCreationConflict = Cannot create branch {0} since it conflicts with branch {1}.
pluginFailed = Plugin JavaScript {0} failed to load

View File

@ -18,6 +18,8 @@ import static com.google.inject.Scopes.SINGLETON;
import static com.google.gerrit.extensions.registration.PrivateInternals_DynamicTypes.registerInParentInjectors;
import com.google.gerrit.common.data.GerritConfig;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.webui.WebUiPlugin;
import com.google.gerrit.httpd.auth.become.BecomeAnyAccountLoginServlet;
import com.google.gerrit.httpd.auth.container.HttpAuthModule;
import com.google.gerrit.httpd.auth.container.HttpsClientSslCertModule;
@ -130,6 +132,7 @@ public class WebModule extends FactoryModule {
SINGLETON);
bind(GerritConfigProvider.class);
bind(GerritConfig.class).toProvider(GerritConfigProvider.class);
DynamicSet.setOf(binder(), WebUiPlugin.class);
bind(AccountManager.class);
bind(ChangeUserName.CurrentUser.class);

View File

@ -501,6 +501,10 @@ class HttpPluginServlet extends HttpServlet
}
if (contentType == null) {
contentType = mimeUtil.getMimeType(entry.getName(), data).toString();
if ("application/octet-stream".equals(contentType)
&& entry.getName().endsWith(".js")) {
contentType = "application/javascript";
}
}
long time = entry.getTime();

View File

@ -16,8 +16,12 @@ package com.google.gerrit.httpd.raw;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.google.common.collect.Lists;
import com.google.common.primitives.Bytes;
import com.google.gerrit.common.data.GerritConfig;
import com.google.gerrit.common.data.HostPageData;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.webui.WebUiPlugin;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.server.CurrentUser;
@ -45,6 +49,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
@ -65,6 +70,7 @@ public class HostPageServlet extends HttpServlet {
private final Provider<CurrentUser> currentUser;
private final Provider<WebSession> session;
private final GerritConfig config;
private final DynamicSet<WebUiPlugin> plugins;
private final HostPageData.Theme signedOutTheme;
private final HostPageData.Theme signedInTheme;
private final SitePaths site;
@ -78,11 +84,13 @@ public class HostPageServlet extends HttpServlet {
HostPageServlet(final Provider<CurrentUser> cu, final Provider<WebSession> w,
final SitePaths sp, final ThemeFactory themeFactory,
final GerritConfig gc, final ServletContext servletContext,
final DynamicSet<WebUiPlugin> webUiPlugins,
@GerritServerConfig final Config cfg)
throws IOException, ServletException {
currentUser = cu;
session = w;
config = gc;
plugins = webUiPlugins;
signedOutTheme = themeFactory.getSignedOutTheme();
signedInTheme = themeFactory.getSignedInTheme();
site = sp;
@ -163,11 +171,9 @@ public class HostPageServlet extends HttpServlet {
protected void doGet(final HttpServletRequest req,
final HttpServletResponse rsp) throws IOException {
final Page.Content page = get().get(select(req));
final byte[] raw;
final StringWriter w = new StringWriter();
final CurrentUser user = currentUser.get();
if (user instanceof IdentifiedUser) {
final StringWriter w = new StringWriter();
w.write(HPD_ID + ".account=");
json(((IdentifiedUser) user).getAccount(), w);
w.write(";");
@ -183,17 +189,19 @@ public class HostPageServlet extends HttpServlet {
w.write(HPD_ID + ".theme=");
json(signedInTheme, w);
w.write(";");
final byte[] userData = w.toString().getBytes("UTF-8");
raw = concat(page.part1, userData, page.part2);
} else {
raw = page.full;
w.write(HPD_ID + ".theme=");
json(signedOutTheme, w);
w.write(";");
}
plugins(w);
final byte[] hpd = w.toString().getBytes("UTF-8");
final byte[] raw = Bytes.concat(page.part1, hpd, page.part2);
final byte[] tosend;
if (RPCServletUtils.acceptsGzipEncoding(req)) {
rsp.setHeader("Content-Encoding", "gzip");
tosend = raw == page.full ? page.full_gz : HtmlDomUtil.compress(raw);
tosend = HtmlDomUtil.compress(raw);
} else {
tosend = raw;
}
@ -212,6 +220,20 @@ public class HostPageServlet extends HttpServlet {
}
}
private void plugins(StringWriter w) {
List<String> urls = Lists.newArrayList();
for (WebUiPlugin u : plugins) {
urls.add(String.format("plugins/%s/%s",
u.getPluginName(),
u.getJavaScriptResourcePath()));
}
if (!urls.isEmpty()) {
w.write(HPD_ID + ".plugins=");
json(urls, w);
w.write(";");
}
}
private Permutation select(final HttpServletRequest req) {
if ("0".equals(req.getParameter("s"))) {
// If s=0 is used in the URL, the user has explicitly asked us
@ -223,20 +245,6 @@ public class HostPageServlet extends HttpServlet {
return selector.select(req);
}
private static byte[] concat(byte[] p1, byte[] p2, byte[] p3) {
final byte[] r = new byte[p1.length + p2.length + p3.length];
int p = 0;
p = append(p1, r, p);
p = append(p2, r, p);
p = append(p3, r, p);
return r;
}
private static int append(byte[] src, final byte[] dst, int p) {
System.arraycopy(src, 0, dst, p, src.length);
return p + src.length;
}
private static class FileInfo {
private final File path;
private final long time;
@ -313,8 +321,6 @@ public class HostPageServlet extends HttpServlet {
class Content {
final byte[] part1;
final byte[] part2;
final byte[] full;
final byte[] full_gz;
Content(Document hostDoc) throws IOException {
final String raw = HtmlDomUtil.toString(hostDoc);
@ -324,15 +330,6 @@ public class HostPageServlet extends HttpServlet {
}
part1 = raw.substring(0, p).getBytes("UTF-8");
part2 = raw.substring(raw.indexOf('>', p) + 1).getBytes("UTF-8");
final StringWriter w = new StringWriter();
w.write(HPD_ID + ".theme=");
json(signedOutTheme, w);
w.write(";");
final byte[] themeData = w.toString().getBytes("UTF-8");
full = concat(part1, themeData, part2);
full_gz = HtmlDomUtil.compress(full);
}
}

6
gerrit-plugin-gwtui/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/target
/.classpath
/.project
/.settings/org.maven.ide.eclipse.prefs
/.settings/org.eclipse.m2e.core.prefs
/gerrit-gwtui-plugin.iml

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8

View File

@ -0,0 +1,295 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.codeComplete.argumentPrefixes=
org.eclipse.jdt.core.codeComplete.argumentSuffixes=
org.eclipse.jdt.core.codeComplete.fieldPrefixes=
org.eclipse.jdt.core.codeComplete.fieldSuffixes=
org.eclipse.jdt.core.codeComplete.localPrefixes=
org.eclipse.jdt.core.codeComplete.localSuffixes=
org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=16
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=0
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=0
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=2
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=true
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=3
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=2
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true

View File

@ -0,0 +1,7 @@
eclipse.preferences.version=1
formatter_profile=_Google Format
formatter_settings_version=12
org.eclipse.jdt.ui.exception.name=e
org.eclipse.jdt.ui.gettersetter.use.is=true
org.eclipse.jdt.ui.keywordthis=false
org.eclipse.jdt.ui.overrideannotation=true

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2012 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
<version>2.6-SNAPSHOT</version>
</parent>
<artifactId>gerrit-plugin-gwtui</artifactId>
<name>Gerrit Code Review - Plugin GWT UI</name>
<description>
API for UI plugins to build with GWT and integrate with Gerrit
</description>
<dependencies>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<configuration>
<module>com.google.gerrit.Plugin</module>
<disableClassMetadata>true</disableClassMetadata>
<disableCastChecking>true</disableCastChecking>
</configuration>
<executions>
<execution>
<goals>
<goal>resources</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,23 @@
<!--
Copyright (C) 2012 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<module>
<define-linker name="gerrit_plugin" class="com.google.gerrit.linker.GerritPluginLinker"/>
<add-linker name="gerrit_plugin"/>
<generate-with class="com.google.gerrit.rebind.PluginGenerator">
<when-type-assignable class="com.google.gerrit.client.Plugin"/>
</generate-with>
<source path="client"/>
</module>

View File

@ -0,0 +1,29 @@
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.client;
import com.google.gwt.core.client.EntryPoint;
/**
* Base class for writing Gerrit Web UI plugins
*
* Writing a plugin:
* <ol>
* <li>Declare subtype of Plugin</li>
* <li>Bind WebUiPlugin to GwtPlugin implementation in Gerrit-Module</li>
* </ol>
*/
public abstract class Plugin implements EntryPoint {
}

View File

@ -0,0 +1,31 @@
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.linker;
import com.google.gwt.core.ext.LinkerContext;
import com.google.gwt.core.linker.CrossSiteIframeLinker;
/** Finalizes the module manifest file with the selection script. */
public final class GerritPluginLinker extends CrossSiteIframeLinker {
@Override
public String getDescription() {
return "Gerrit GWT UI plugin";
}
@Override
protected String getJsComputeUrlForResource(LinkerContext context) {
return "com/google/gerrit/linker/computeUrlForPluginResource.js";
}
}

View File

@ -0,0 +1,95 @@
// Copyright (C) 2012 The Android Open Source Project
// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.rebind;
import java.io.PrintWriter;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
/**
* Write the top layer in the Gadget bootstrap sandwich and generate a stub
* manifest that will be completed by the linker.
*
* Based on gwt-gadgets GadgetGenerator class
*/
public class PluginGenerator extends Generator {
@Override
public String generate(TreeLogger logger, GeneratorContext context,
String typeName) throws UnableToCompleteException {
// The TypeOracle knows about all types in the type system
TypeOracle typeOracle = context.getTypeOracle();
// Get a reference to the type that the generator should implement
JClassType sourceType = typeOracle.findType(typeName);
// Ensure that the requested type exists
if (sourceType == null) {
logger.log(TreeLogger.ERROR, "Could not find requested typeName", null);
throw new UnableToCompleteException();
}
// Make sure the Gadget type is correctly defined
validateType(logger, sourceType);
// Pick a name for the generated class to not conflict.
String generatedSimpleSourceName = sourceType.getSimpleSourceName()
+ "PluginImpl";
// Begin writing the generated source.
ClassSourceFileComposerFactory f = new ClassSourceFileComposerFactory(
sourceType.getPackage().getName(), generatedSimpleSourceName);
f.addImport(GWT.class.getName());
f.setSuperclass(typeName);
// All source gets written through this Writer
PrintWriter out = context.tryCreate(logger,
sourceType.getPackage().getName(), generatedSimpleSourceName);
// If an implementation already exists, we don't need to do any work
if (out != null) {
// We really use a SourceWriter since it's convenient
SourceWriter sw = f.createSourceWriter(context, out);
sw.println("public " + generatedSimpleSourceName + "() {");
sw.indent();
sw.println("onModuleLoad();");
sw.outdent();
sw.println("}");
sw.commit(logger);
}
return f.getCreatedClassName();
}
protected void validateType(TreeLogger logger, JClassType type)
throws UnableToCompleteException {
if (!type.isDefaultInstantiable()) {
logger.log(TreeLogger.ERROR, "Plugin types must be default instantiable",
null);
throw new UnableToCompleteException();
}
}
}

View File

@ -0,0 +1,3 @@
function computeUrlForResource(resource) {
return __MODULE_FUNC__.__moduleBase + resource;
}

View File

@ -98,7 +98,8 @@ limitations under the License.
<modules>
<module>gerrit-plugin-api</module>
<module>gerrit-plugin-archetype</module>
</modules>
<module>gerrit-plugin-gwtui</module>
</modules>
</profile>
<profile>
<activation>