diff options
28 files changed, 136 insertions, 721 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/.classpath b/eclipse/plugins/com.android.ide.eclipse.adt/.classpath index 72ca4ed..2f2f6a9 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/.classpath +++ b/eclipse/plugins/com.android.ide.eclipse.adt/.classpath @@ -5,7 +5,6 @@ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="lib" path="libs/androidprefs.jar" sourcepath="/AndroidPrefs"/> <classpathentry kind="lib" path="libs/commons-compress-1.0.jar"/> - <classpathentry kind="lib" path="libs/groovy-all-1.7.0.jar" sourcepath="/GroovySrc/groovy-src-1.7.0.zip"/> <classpathentry kind="lib" path="libs/kxml2-2.3.0.jar"/> <classpathentry kind="lib" path="libs/layoutlib_api.jar"/> <classpathentry kind="lib" path="libs/layoutlib_utils.jar"/> diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF index 1f66e2a..6145db2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF +++ b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF @@ -10,7 +10,6 @@ Bundle-ClassPath: ., libs/ninepatch.jar, libs/sdkstats.jar, libs/commons-compress-1.0.jar, - libs/groovy-all-1.7.0.jar, libs/kxml2-2.3.0.jar, libs/layoutlib_api.jar, libs/layoutlib_utils.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/about.html b/eclipse/plugins/com.android.ide.eclipse.adt/about.html index 2892e5d..baa6af1 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/about.html +++ b/eclipse/plugins/com.android.ide.eclipse.adt/about.html @@ -13,7 +13,6 @@ <pre> Note: kxml2-2.3.0.jar is under the BSD license rather than the EPL. You can find a copy of the BSD License at http://www.opensource.org/licenses/bsd-license.php - Note: groovy-all-1.7.0.jar is under a BSD/Apache license rather than the EPL. For details, please see http://groovy.codehaus.org/faq.html#licence . Eclipse Public License - v 1.0 @@ -106,4 +105,4 @@ This Agreement is governed by the laws of the State of New York and the intellec </pre> </body> -</html>
\ No newline at end of file +</html> diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/build.properties b/eclipse/plugins/com.android.ide.eclipse.adt/build.properties index fdd7c71..9eb0d29 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/build.properties +++ b/eclipse/plugins/com.android.ide.eclipse.adt/build.properties @@ -4,7 +4,6 @@ bin.includes = plugin.xml,\ .,\ templates/,\ about.ini,\ - gscripts/,\ libs/,\ about.properties,\ NOTICE,\ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IViewRule.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IViewRule.java index 71c14e3..13699b4 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IViewRule.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IViewRule.java @@ -24,13 +24,12 @@ import java.util.Map; * An {@link IViewRule} describes the GLE rules that apply to a given Layout or View object * in the Graphical Layout Editor (GLE). * <p/> - * Such a rule is implemented using a Groovy script located in the - * com.android.ide.eclipse.adt.internal.editors.layout.gre package or in a - * projects' /gscript folder for custom views. + * Such a rule is implemented by builtin layout helpers, or 3rd party layout rule implementations + * provided with or for a given 3rd party widget. * <p/> - * The Groovy script must be named using the fully qualified class name of the View or Layout, - * e.g. "android.widget.LinearLayout.groovy". If the rule engine can't find a groovy script - * for a given element, it will use the closest matching parent (e.g. View instead of ViewGroup). + * A 3rd party layout rule should use the same fully qualified class name as the layout it + * represents, plus "Rule" as a suffix. For example, the layout rule for the + * LinearLayout class is LinearLayoutRule, in the same package. * <p/> * Rule instances are stateless. They are created once per View class to handle and are shared * across platforms or editor instances. As such, rules methods should never cache editor-specific diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/BaseLayout.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/BaseLayout.java index 13b335e..2a2102a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/BaseLayout.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/BaseLayout.java @@ -81,7 +81,7 @@ public class BaseLayout extends BaseView { * The default behavior for pasting in a layout with a specific child target * is to simulate a drop right above the top left of the given child target. * <p/> - * This method is invoked by BaseView.groovy when onPaste() is called -- + * This method is invoked by BaseView when onPaste() is called -- * views don't generally accept children and instead use the target node as * a hint to paste "before" it. */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ExplodedRenderingHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ExplodedRenderingHelper.java index be882a7..e06ad40 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ExplodedRenderingHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ExplodedRenderingHelper.java @@ -44,7 +44,7 @@ import java.util.Map.Entry; * * TODO * - find a better class name :) - * - move the logic for each layout to groovy scripts? + * - move the logic for each layout to the layout rule classes? * - support custom classes (by querying JDT for its super class and reverting to its behavior) */ public final class ExplodedRenderingHelper { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java index 2e53806..fb7ccfa 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java @@ -45,7 +45,7 @@ import java.util.regex.Pattern; /** * Helper class that is responsible for adding and managing the dynamic menu items - * contributed by the {@link IViewRule} groovy instances, based on the current selection + * contributed by the {@link IViewRule} instances, based on the current selection * on the {@link LayoutCanvas}. * <p/> * This class is tied to a specific {@link LayoutCanvas} instance and a root {@link MenuManager}. @@ -68,7 +68,7 @@ import java.util.regex.Pattern; /** * Creates a new helper responsible for adding and managing the dynamic menu items - * contributed by the {@link IViewRule} groovy instances, based on the current selection + * contributed by the {@link IViewRule} instances, based on the current selection * on the {@link LayoutCanvas}. * * @param canvas The {@link LayoutCanvas} providing the selection, the node factory and @@ -269,7 +269,7 @@ import java.util.regex.Pattern; } /** - * Returns the menu actions computed by the groovy rule associated with this view. + * Returns the menu actions computed by the rule associated with this view. */ public List<MenuAction> getMenuActions(CanvasViewInfo vi) { if (vi == null) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java index 883a40b..2c77c9b 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java @@ -172,7 +172,7 @@ public class GraphicalEditorPart extends EditorPart /** The layout canvas displayed to the right of the sash. */ private LayoutCanvasViewer mCanvasViewer; - /** The Groovy Rules Engine associated with this editor. It is project-specific. */ + /** The Rules Engine associated with this editor. It is project-specific. */ private RulesEngine mRulesEngine; /** Styled text displaying the most recent error in the error view. */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java index 3e5bdcf..44a2e74 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java @@ -154,7 +154,7 @@ class LayoutCanvas extends Canvas implements ISelectionProvider { /** The layout editor that uses this layout canvas. */ private final LayoutEditor mLayoutEditor; - /** The Groovy Rules Engine, associated with the current project. */ + /** The Rules Engine, associated with the current project. */ private RulesEngine mRulesEngine; /** SWT clipboard instance. */ @@ -459,12 +459,12 @@ class LayoutCanvas extends Canvas implements ISelectionProvider { return mLastValidViewInfoRoot == null; } - /** Returns the Groovy Rules Engine, associated with the current project. */ + /** Returns the Rules Engine, associated with the current project. */ /* package */ RulesEngine getRulesEngine() { return mRulesEngine; } - /** Sets the Groovy Rules Engine, associated with the current project. */ + /** Sets the Rules Engine, associated with the current project. */ /* package */ void setRulesEngine(RulesEngine rulesEngine) { mRulesEngine = rulesEngine; } @@ -1964,7 +1964,7 @@ class LayoutCanvas extends Canvas implements ISelectionProvider { * copy, cut, paste and show in > explorer. This is created by * {@link #setupStaticMenuActions(IMenuManager)}. * <p/> - * There's also a dynamic part that is populated by the groovy rules of the + * There's also a dynamic part that is populated by the rules of the * selected elements, created by {@link DynamicContextMenu}. */ private void createContextMenu() { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeFactory.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeFactory.java index 022d233..f4ebc23 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeFactory.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeFactory.java @@ -46,7 +46,7 @@ public class NodeFactory { /** * Returns an {@link INode} proxy based on a given {@link UiViewElementNode} that - * is not yet part of the canvas, typically those created by groovy scripts + * is not yet part of the canvas, typically those created by layout rules * when generating new XML. */ public NodeProxy create(UiViewElementNode uiNode) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java index 30782bf..c6c84a7 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java @@ -362,7 +362,7 @@ public class NodeProxy implements INode { * Helper methods that returns a {@link ViewElementDescriptor} for the requested FQCN. * Will return null if we can't find that FQCN or we lack the editor/data/descriptors info * (which shouldn't really happen since at this point the SDK should be fully loaded and - * isn't reloading, or we wouldn't be here editing XML for a groovy script.) + * isn't reloading, or we wouldn't be here editing XML for a layout rule.) */ private ViewElementDescriptor getFqcnViewDescritor(String fqcn) { AndroidXmlEditor editor = mNode.getEditor(); @@ -375,7 +375,7 @@ public class NodeProxy implements INode { private void warnPrintf(String msg, Object...params) { AdtPlugin.printToConsole( - mNode == null ? "Groovy" : mNode.getDescriptor().getXmlLocalName() + ".groovy", + mNode == null ? "" : mNode.getDescriptor().getXmlLocalName(), String.format(msg, params) ); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java index d492a7a..8de095d 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java @@ -27,117 +27,119 @@ import com.android.ide.common.api.MenuAction; import com.android.ide.common.api.Point; import com.android.ide.common.layout.ViewRule; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AndroidConstants; import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor; import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SimpleElement; import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFolderListener; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; +import com.android.ide.eclipse.adt.internal.sdk.ProjectState; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkConstants; -import com.android.sdklib.annotations.VisibleForTesting; -import com.android.sdklib.annotations.VisibleForTesting.Visibility; - -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.CompilerConfiguration; -import org.codehaus.groovy.control.Phases; -import org.codehaus.groovy.control.SourceUnit; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; +import com.android.sdklib.internal.project.ProjectProperties; + import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; -import groovy.lang.ExpandoMetaClass; -import groovy.lang.GroovyClassLoader; -import groovy.lang.GroovyCodeSource; -import groovy.lang.GroovyObject; -import groovy.lang.GroovyResourceLoader; - -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.File; import java.net.MalformedURLException; -import java.net.URI; import java.net.URL; -import java.nio.charset.Charset; -import java.security.CodeSource; +import java.net.URLClassLoader; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; /** - * The rule engine manages the groovy rules files and interacts with them. + * The rule engine manages the layout rules and interacts with them. * There's one {@link RulesEngine} instance per layout editor. - * Each instance has 2 sets of scripts: the static ADT rules (shared across all instances) + * Each instance has 2 sets of rules: the static ADT rules (shared across all instances) * and the project specific rules (local to the current instance / layout editor). */ public class RulesEngine { + private final IProject mProject; + private final Map<Object, IViewRule> mRulesCache = new HashMap<Object, IViewRule>(); /** - * The project folder where the scripts are located. - * This is for both our unique ADT project folder and the user projects folders. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - public static final String FD_GSCRIPTS = "gscripts"; //$NON-NLS-1$ - /** - * The extension we expect for the groovy scripts. + * Class loader (or null) used to load user/project-specific IViewRule + * classes */ - private static final String SCRIPT_EXT = ".groovy"; //$NON-NLS-1$ + private ClassLoader mUserClassLoader; + /** - * The package we expect for our groovy scripts. - * User scripts do not need to use the same (and in fact should probably not.) + * Flag set when we've attempted to initialize the {@link #mUserClassLoader} + * already */ - private static final String SCRIPT_PACKAGE = "com.android.adt.gscripts"; //$NON-NLS-1$ - - private final GroovyClassLoader mClassLoader; - private final IProject mProject; - private final Map<Object, IViewRule> mRulesCache = new HashMap<Object, IViewRule>(); - private ProjectFolderListener mProjectFolderListener; - + private boolean mUserClassLoaderInited; /** * Creates a new {@link RulesEngine} associated with the selected project. * <p/> - * The rules engine will look in the projects "/gscripts" folder for custom view rules. + * The rules engine will look in the project for a tools jar to load custom view rules. * * @param project A non-null open project. */ public RulesEngine(IProject project) { mProject = project; - ClassLoader cl = getClass().getClassLoader(); - - // Note: we could use the CompilerConfiguration to add an output log collector - CompilerConfiguration cc = new CompilerConfiguration(); - cc.setDefaultScriptExtension(SCRIPT_EXT); + } - mClassLoader = new GreGroovyClassLoader(cl, cc); + /** + * Find out whether the given project has 3rd party ViewRules, and if so + * return a ClassLoader which can locate them. If not, return null. + * @param project The project to load user rules from + * @return A class loader which can user view rules, or otherwise null + */ + private static ClassLoader computeUserClassLoader(IProject project) { + // Default place to locate layout rules. The user may also add to this + // path by defining a config property specifying + // additional .jar files to search via a the layoutrules.jars property. + ProjectState state = Sdk.getProjectState(project); + ProjectProperties projectProperties = state.getProperties(); + + // Ensure we have the latest & greatest version of the properties. + // This allows users to reopen editors in a running Eclipse instance + // to get updated view rule jars + projectProperties.reload(); + + String path = projectProperties.getProperty( + ProjectProperties.PROPERTY_RULES_PATH); + + if (path != null && path.length() > 0) { + List<URL> urls = new ArrayList<URL>(); + String[] pathElements = path.split(File.pathSeparator); + for (String pathElement : pathElements) { + pathElement = pathElement.trim(); // Avoid problems with trailing whitespace etc + File pathFile = new File(pathElement); + if (!pathFile.isAbsolute()) { + pathFile = new File(project.getLocation().toFile(), pathElement); + } + // Directories and jar files are okay. Do we need to + // validate the files here as .jar files? + if (pathFile.isFile() || pathFile.isDirectory()) { + URL url; + try { + url = pathFile.toURI().toURL(); + urls.add(url); + } catch (MalformedURLException e) { + AdtPlugin.log(IStatus.WARNING, + "Invalid URL: %1$s", //$NON-NLS-1$ + e.toString()); + } + } + } - // Add the project's gscript folder to the classpath, if it exists. - IResource f = project.findMember(FD_GSCRIPTS); - if ((f instanceof IFolder) && f.exists()) { - URI uri = ((IFolder) f).getLocationURI(); - try { - URL url = uri.toURL(); - mClassLoader.addURL(url); - } catch (MalformedURLException e) { - // ignore; it's not a valid URL, we obviously won't use it - // in the class path. + if (urls.size() > 0) { + return new URLClassLoader(urls.toArray(new URL[urls.size()]), + RulesEngine.class.getClassLoader()); } } - mProjectFolderListener = new ProjectFolderListener(); - GlobalProjectMonitor.getMonitor().addFolderListener( - mProjectFolderListener, - IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED); + return null; } /** @@ -152,10 +154,6 @@ public class RulesEngine { * This frees some resources, such as the project's folder monitor. */ public void dispose() { - if (mProjectFolderListener != null) { - GlobalProjectMonitor.getMonitor().removeFolderListener(mProjectFolderListener); - mProjectFolderListener = null; - } clearCache(); } @@ -172,7 +170,7 @@ public class RulesEngine { * * @param element The view element to target. Can be null. * @return Null if the rule failed, there's no rule or the rule does not want to override - * the display name. Otherwise, a string as returned by the groovy script. + * the display name. Otherwise, a string as returned by the rule. */ public String callGetDisplayName(UiViewElementNode element) { // try to find a rule for this element's FQCN @@ -418,16 +416,6 @@ public class RulesEngine { return null; } - private class ProjectFolderListener implements IFolderListener { - public void folderChanged(IFolder folder, int kind) { - if (folder.getProject() == mProject && - FD_GSCRIPTS.equals(folder.getName())) { - // Clear our whole rules cache, to not have to deal with dependencies. - clearCache(); - } - } - } - /** * Clear the Rules cache. Calls onDispose() on each rule. */ @@ -525,11 +513,11 @@ public class RulesEngine { * Once a rule is found (or not), it is stored in a cache using its target FQCN * so we don't try to reload it. * <p/> - * The real FQCN is the actual groovy filename we're loading, e.g. "android.view.View.groovy" + * The real FQCN is the actual rule class we're loading, e.g. "android.view.View" * where target FQCN is the class we were initially looking for, which might be the same as * the real FQCN or might be a derived class, e.g. "android.widget.TextView". * - * @param realFqcn The FQCN of the groovy rule actually being loaded. + * @param realFqcn The FQCN of the rule class actually being loaded. * @param targetFqcn The FQCN of the class actually processed, which might be different from * the FQCN of the rule being loaded. */ @@ -545,32 +533,53 @@ public class RulesEngine { return rule; } - // Look for class via reflection first + // Look for class via reflection try { - int dotIndex = realFqcn.lastIndexOf('.'); - String baseName = realFqcn.substring(dotIndex+1); - // For now, we package view rules for the builtin Android views and // widgets with the tool in a special package, so look there rather // than in the same package as the widgets. - String packageName; + String ruleClassName; + ClassLoader classLoader; if (realFqcn.startsWith("android.")) { //$NON-NLS-1$ // This doesn't handle a case where there are name conflicts // (e.g. where there are multiple different views with the same // class name and only differing in package names, but that's a // really bad practice in the first place, and if that situation // should come up in the API we can enhance this algorithm. - packageName = ViewRule.class.getName(); + String packageName = ViewRule.class.getName(); packageName = packageName.substring(0, packageName.lastIndexOf('.')); + classLoader = RulesEngine.class.getClassLoader(); + int dotIndex = realFqcn.lastIndexOf('.'); + String baseName = realFqcn.substring(dotIndex+1); + ruleClassName = packageName + "." + //$NON-NLS-1$ + baseName + "Rule"; //$NON-NLS-1$ + } else { + // Initialize the user-classpath for 3rd party IViewRules, if necessary + if (mUserClassLoader == null) { + // Only attempt to load rule paths once (per RulesEngine instance); + if (!mUserClassLoaderInited) { + mUserClassLoaderInited = true; + mUserClassLoader = computeUserClassLoader(mProject); + } + + if (mUserClassLoader == null) { + // The mUserClassLoader can be null; this is the typical scenario, + // when the user is only using builtin layout rules. + // This means however we can't resolve this fqcn since it's not + // in the name space of the builtin rules. + mRulesCache.put(realFqcn, null); + return null; + } + } + // For other (3rd party) widgets, look in the same package (though most // likely not in the same jar!) - packageName = realFqcn.substring(0, dotIndex); + ruleClassName = realFqcn + "Rule"; //$NON-NLS-1$ + classLoader = mUserClassLoader; } - String ruleClassName = packageName + "." + //$NON-NLS-1$ - baseName + "Rule"; //$NON-NLS-1$ - Class<?> clz = Class.forName(ruleClassName); + Class<?> clz = Class.forName(ruleClassName, true, classLoader); rule = (IViewRule) clz.newInstance(); return initializeRule(rule, targetFqcn); } catch (ClassNotFoundException ex) { @@ -584,39 +593,6 @@ public class RulesEngine { logError("load rule error (%s): %s", realFqcn, e.toString()); } - // Look for the file in ADT first. - // That means a project can't redefine any of the rules we define. - String filename = realFqcn + SCRIPT_EXT; - - try { - InputStream is = AdtPlugin.readEmbeddedFileAsStream( - FD_GSCRIPTS + AndroidConstants.WS_SEP + filename); - rule = loadStream(is, realFqcn, "ADT"); //$NON-NLS-1$ - if (rule != null) { - return initializeRule(rule, targetFqcn); - } - } catch (Exception e) { - logError("load rule error (%s): %s", filename, e.toString()); - } - - - // Then look for the file in the project - IResource r = mProject.findMember(FD_GSCRIPTS); - if (r != null && r.getType() == IResource.FOLDER) { - r = ((IFolder) r).findMember(filename); - if (r != null && r.getType() == IResource.FILE) { - try { - InputStream is = ((IFile) r).getContents(); - rule = loadStream(is, realFqcn, mProject.getName()); - if (rule != null) { - return initializeRule(rule, targetFqcn); - } - } catch (Exception e) { - logError("load rule error (%s): %s", filename, e.getMessage()); - } - } - } - // Memorize in the cache that we couldn't find a rule for this real FQCN mRulesCache.put(realFqcn, null); return null; @@ -629,7 +605,7 @@ public class RulesEngine { * Contract: the rule is not in the {@link #mRulesCache} yet and this method will * cache it using the target FQCN if the rule is accepted. * <p/> - * The real FQCN is the actual groovy filename we're loading, e.g. "android.view.View.groovy" + * The real FQCN is the actual rule class we're loading, e.g. "android.view.View" * where target FQCN is the class we were initially looking for, which might be the same as * the real FQCN or might be a derived class, e.g. "android.widget.TextView". * @@ -641,10 +617,6 @@ public class RulesEngine { private IViewRule initializeRule(IViewRule rule, String targetFqcn) { try { - if (rule instanceof GroovyObject) { - initializeMetaClass((GroovyObject) rule, targetFqcn); - } - if (rule.onInitialize(targetFqcn, new ClientRulesEngineImpl(targetFqcn))) { // Add it to the cache and return it mRulesCache.put(targetFqcn, rule); @@ -662,73 +634,6 @@ public class RulesEngine { } /** - * Initializes a custom meta class for the given {@link GroovyObject}. - * This is used to add a meta "_rules_engine" property to the {@link IViewRule} instances. - * - * @param instance The {@link IViewRule} groovy object to modify. - * @param targetFqcn The FQCN for the new {@link IClientRulesEngine}. - */ - private void initializeMetaClass(GroovyObject instance, final String targetFqcn) { - - final ClientRulesEngineImpl mClient = new ClientRulesEngineImpl(targetFqcn); - - ExpandoMetaClass mc = new ExpandoMetaClass(instance.getClass(), false) { - @Override - public Object getProperty(Object object, String name) { - if (IViewRule.RULES_ENGINE.equals(name)) { - return mClient; - } - return super.getProperty(object, name); - } - }; - mc.initialize(); - - instance.setMetaClass(mc); - } - - /** - * Actually load a groovy script and instantiate an {@link IViewRule} from it. - * On error, outputs (hopefully meaningful) groovy error messages. - * - * @param is The input stream for the groovy script. Can be null. - * @param fqcn The class name, for display purposes only. - * @param codeBase A string eventually passed to {@link CodeSource} to define some kind - * of security permission. Quite irrelevant in our case since it all - * comes from an input stream. However this method uses it to print - * the origin of the source in the exception errors. - * @return A new {@link IViewRule} or null if loading failed for any reason. - */ - private IViewRule loadStream(InputStream is, String fqcn, String codeBase) { - try { - if (is == null) { - // We handle this case for convenience. It typically means that the - // input stream couldn't be opened because the file was not found. - // Since we expect this to be a common case, we don't log it as an error. - return null; - } - - // We don't really now the character encoding, we're going to assume UTF-8. - InputStreamReader reader = new InputStreamReader(is, Charset.forName("UTF-8")); - GroovyCodeSource source = new GroovyCodeSource(reader, fqcn, codeBase); - - // Create a groovy class from it. Can fail to compile. - Class<?> c = mClassLoader.parseClass(source); - - // Get an instance. This might throw ClassCastException. - return (IViewRule) c.newInstance(); - - } catch (CompilationFailedException e) { - logError("Compilation error in %1$s:%2$s.groovy: %3$s", codeBase, fqcn, e.toString()); - } catch (ClassCastException e) { - logError("Script %1$s:%2$s.groovy does not implement IViewRule", codeBase, fqcn); - } catch (Exception e) { - logError("Failed to use %1$s:%2$s.groovy: %3$s", codeBase, fqcn, e.toString()); - } - - return null; - } - - /** * Logs an error to the console. * * @param format A format string following the format specified by @@ -740,83 +645,6 @@ public class RulesEngine { AdtPlugin.printErrorToConsole(mProject, s); } - // ----- - - /** - * A custom {@link GroovyClassLoader} that lets us override the {@link CompilationUnit} - * and the {@link GroovyResourceLoader}. - */ - private static class GreGroovyClassLoader extends GroovyClassLoader { - - public GreGroovyClassLoader(ClassLoader cl, CompilerConfiguration cc) { - super(cl, cc); - - // Override the resource loader: when a class is not found, we try to find a class - // defined in our internal ADT groovy script, assuming it has our special package. - // Note that these classes do not have to implement IViewRule. That means we can - // create utility classes in groovy used by the other groovy rules. - final GroovyResourceLoader resLoader = getResourceLoader(); - setResourceLoader(new GroovyResourceLoader() { - public URL loadGroovySource(String filename) throws MalformedURLException { - URL url = resLoader.loadGroovySource(filename); - if (url == null) { - // We only try to load classes in our own groovy script package - String p = SCRIPT_PACKAGE + "."; //$NON-NLS-1$ - - if (filename.startsWith(p)) { - filename = filename.substring(p.length()); - - // This will return null if the file doesn't exists. - // The groovy resolver will actually load and verify the class - // implemented matches the one it was expecting in the first place, - // so we don't have anything to do here besides returning the URL to - // the source file. - url = AdtPlugin.getEmbeddedFileUrl( - AndroidConstants.WS_SEP + - FD_GSCRIPTS + - AndroidConstants.WS_SEP + - filename + - SCRIPT_EXT); - } - } - return url; - } - }); - } - - @Override - protected CompilationUnit createCompilationUnit( - CompilerConfiguration config, - CodeSource source) { - return new GreCompilationUnit(config, source, this); - } - } - - /** - * A custom {@link CompilationUnit} that lets us add default import for our base classes - * using the base package of {@link IViewRule} (e.g. "import com.android...gscripts.*") - */ - private static class GreCompilationUnit extends CompilationUnit { - - public GreCompilationUnit( - CompilerConfiguration config, - CodeSource source, - GroovyClassLoader loader) { - super(config, source, loader); - - SourceUnitOperation op = new SourceUnitOperation() { - @Override - public void call(SourceUnit source) throws CompilationFailedException { - // add the equivalent of "import com.android...gscripts.*" to the source. - String p = IViewRule.class.getPackage().getName(); - source.getAST().addStarImport(p + "."); //$NON-NLS-1$ - } - }; - - addPhaseOperation(op, Phases.CONVERSION); - } - } - /** * Implementation of {@link IClientRulesEngine}. This provide {@link IViewRule} clients * with a few methods they can use to use functionality from this {@link RulesEngine}. @@ -835,7 +663,7 @@ public class RulesEngine { public void debugPrintf(String msg, Object... params) { AdtPlugin.printToConsole( - mFqcn == null ? "Groovy" : mFqcn, + mFqcn == null ? "<unknown>" : mFqcn, String.format(msg, params) ); } diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/.classpath b/eclipse/plugins/com.android.ide.eclipse.tests/.classpath index 1f2b3ec..9164986 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/.classpath +++ b/eclipse/plugins/com.android.ide.eclipse.tests/.classpath @@ -6,7 +6,6 @@ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="lib" path="layoutlib.jar"/> <classpathentry kind="lib" path="kxml2-2.3.0.jar"/> - <classpathentry kind="lib" path="groovy-all-1.7.0.jar"/> <classpathentry kind="lib" path="easymock.jar"/> <classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/> <classpathentry combineaccessrules="false" kind="src" path="/ddmuilib"/> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF index 549611f..36e25e0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF +++ b/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF @@ -10,5 +10,4 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ClassPath: kxml2-2.3.0.jar, ., layoutlib.jar, - groovy-all-1.7.0.jar, easymock.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/build.properties b/eclipse/plugins/com.android.ide.eclipse.tests/build.properties index 7c9915c..eece9f2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/build.properties +++ b/eclipse/plugins/com.android.ide.eclipse.tests/build.properties @@ -11,6 +11,5 @@ bin.includes = META-INF/,\ unittests/com/android/sdklib/testdata/,\ unittests/com/android/layoutlib/testdata/,\ unittests/com/android/ide/eclipse/testdata/,\ - groovy-all-1.7.0.jar,\ easymock.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java index ee79336..5386142 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java @@ -1,12 +1,12 @@ /* * Copyright (C) 2008 The Android Open Source Project - * + * * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * + * * 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 @@ -24,9 +24,9 @@ import junit.framework.TestSuite; public class AllTests extends TestSuite { public AllTests() { - + } - + /** * Returns a suite of test cases to be run. */ @@ -34,7 +34,6 @@ public class AllTests extends TestSuite { TestSuite suite = new TestSuite(); suite.addTest(FuncTests.suite()); suite.addTest(UnitTests.suite()); - suite.addTest(GroovyTestsSuite.suite()); return suite; } diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/GroovyTestsSuite.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/GroovyTestsSuite.java deleted file mode 100755 index affc7ec..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/GroovyTestsSuite.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * - * 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.android.ide.eclipse.tests; - -import com.android.ide.eclipse.tests.groovytests.TestGroovy; - -import junit.framework.TestSuite; - -/** - * Container TestSuite for groovy tests to be run - */ - -public class GroovyTestsSuite extends TestSuite { - - static final String GROOVY_TEST_PACKAGE = "com.android.ide.eclipse.tests.groovytests"; - - public GroovyTestsSuite() { - - } - - /** - * Returns a suite of test cases to be run. - * Needed for JUnit3 compliant command line test runner - */ - public static TestSuite suite() { - TestSuite suite = new TestSuite(); - - suite.addTestSuite(TestGroovy.class); - - return suite; - } - -} diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java index 2d74f82..15d3871 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java @@ -55,8 +55,7 @@ public class UnitTests { @Override protected boolean isTestClass(Class<?> testClass) { return super.isTestClass(testClass) && - !testClass.getPackage().getName().startsWith(FuncTests.FUNC_TEST_PACKAGE) && - !testClass.getPackage().getName().startsWith(GroovyTestsSuite.GROOVY_TEST_PACKAGE); + !testClass.getPackage().getName().startsWith(FuncTests.FUNC_TEST_PACKAGE); } } } diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/TestGroovy.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/TestGroovy.java deleted file mode 100755 index 556bce6..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/TestGroovy.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * - * 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.android.ide.eclipse.tests.groovytests; - -import org.codehaus.groovy.control.CompilationFailedException; -import org.eclipse.swt.graphics.Rectangle; - -import groovy.lang.GroovyClassLoader; - -import java.io.FileNotFoundException; -import java.io.InputStream; - -import junit.framework.TestCase; - -/** - * Tests we can invoke a groovy script that implements a given interface. - */ -public class TestGroovy extends TestCase { - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - /** - * This is the interface that we want our Groovy script to implement. - */ - public static interface AdtTestInterface { - - /** Method that returns a boolean. */ - public boolean acceptDrag(String xmlName); - /** Method that returns an SWT Rectangle. */ - public Rectangle acceptDrop(String xmlName); - - /** Method that returns some Groovy object (opaque for us). */ - public Object returnGroovyObject(); - /** Method that accepts the Groovy object back. */ - public boolean testGroovyObject(Object o); - } - - /** - * Loads a groovy script that defines one class that implements the {@link AdtTestInterface}. - * - * @param filename The name of the script to load, that must be located in this Java package. - * @return A non-null instance of the groovy class on success. - * @throws CompilationFailedException if the groovy script failed to compile (e.g. syntax - * errors or it doesn't completely implement the interface.) - * @throws ClassCastException if the groovy script does not implement our interface. - * @throws FileNotFoundException if the groovy script does not exist. - * @throws InstantiationException - * @throws IllegalAccessException - */ - @SuppressWarnings("unchecked") - private AdtTestInterface loadScript(String filename) - throws CompilationFailedException, ClassCastException, - InstantiationException, IllegalAccessException, - FileNotFoundException { - // Get the input source from the sources or the JAR. - InputStream myGroovyStream = getClass().getResourceAsStream(filename); - - // The stream is null if the file does not exists. - if (myGroovyStream == null) { - throw new FileNotFoundException(filename); - } - - // Create a groovy class from it. Can fail to compile. - ClassLoader cl = getClass().getClassLoader(); - GroovyClassLoader gcl = new GroovyClassLoader(cl); - Class gClass = gcl.parseClass(myGroovyStream, filename); - - // Get an instance. This might throw ClassCastException. - return (AdtTestInterface) gClass.newInstance(); - } - - /** - * Tests that a {@link FileNotFoundException} is thrown if when trying - * to load a missing script. - */ - public void testMissingScript() throws Exception { - try { - @SuppressWarnings("unused") - AdtTestInterface instance = loadScript("not_an_existing_script.groovy"); - fail("loadScript should not succeed, FileNotFoundException expected."); - } catch (FileNotFoundException e) { - assertEquals("not_an_existing_script.groovy", e.getMessage()); - return; // succeed - } - - fail("Script failed to throw an exception on missing groovy file."); - } - - /** - * Tests that a {@link ClassCastException} is thrown if the script does not - * implement our interface. - */ - public void testInvalidInterface() throws Exception { - try { - @SuppressWarnings("unused") - AdtTestInterface instance = loadScript("invalid_interface.groovy"); - fail("loadScript should not succeed, ClassCastException expected."); - } catch(ClassCastException e) { - // This has to fail because the script does not implement our interface - // The message explains why but we're not harcoding the message in the test. - assertNotNull(e.getMessage()); - return; // succeed - } - - fail("Script failed to throw a ClassCastException."); - } - - /** - * Tests that a {@link CompilationFailedException} is thrown if the script - * is not valid. - */ - public void testCompilationError() throws Exception { - try { - @SuppressWarnings("unused") - AdtTestInterface instance = loadScript("compile_error.groovy"); - fail("loadScript should not succeed, CompilationFailedException expected."); - } catch (CompilationFailedException e) { - // This script does not compile, the message explains why but we're not - // harcoding the message in the test. - assertNotNull(e.getMessage()); - return; // succeed - } - - fail("Script failed to throw a compilation error."); - } - - /** - * Tests a valid script scenario with only some basic methods - */ - public void testSimpleMethods() throws Exception { - AdtTestInterface instance = loadScript("simple_test.groovy"); - - assertTrue(instance.acceptDrag("LinearLayout")); - assertFalse(instance.acceptDrag("RelativeLayout")); - assertNull(instance.acceptDrop("none")); - - Rectangle r = instance.acceptDrop("LinearLayout"); - assertNotNull(r); - assertEquals(new Rectangle(1, 2, 3, 4), r); - } - - /** - * Tests a valid script scenario with some methods providing some callbacks. - */ - public void testCallback() throws Exception { - AdtTestInterface instance = loadScript("simple_test.groovy"); - - // The groovy method returns an object. We should treat it as an opaque object - // which purpose is just to give it back to groovy later. - Object o = instance.returnGroovyObject(); - assertNotNull(o); - - // Let the groovy script get back the object and play with it - assertTrue(instance.testGroovyObject(o)); - } - - -} diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/compile_error.groovy b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/compile_error.groovy deleted file mode 100755 index 6516c45..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/compile_error.groovy +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * - * 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.android.ide.eclipse.tests.groovytests; - - -import com.android.ide.eclipse.tests.groovytests.TestGroovy.AdtTestInterface; - -import org.eclipse.swt.graphics.Rectangle; - -class CompileError implements AdtTestInterface { - - public boolean acceptDrag(String xmlName) { - // missing return value (implicit in Groovy so not really an error) - } - - // invalid syntax - public Rectangle accept(]) - - // missing method: public Rectangle acceptDrop(String xmlName) -} diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/invalid_interface.groovy b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/invalid_interface.groovy deleted file mode 100755 index 0fa1a86..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/invalid_interface.groovy +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * - * 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.android.ide.eclipse.tests.groovytests; - -class InvalidInterface implements Runnable { - - public void run() { - // pass - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/simple_test.groovy b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/simple_test.groovy deleted file mode 100755 index 7dd96bd..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/simple_test.groovy +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * - * 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.android.ide.eclipse.tests.groovytests; - -import com.android.ide.eclipse.tests.groovytests.TestGroovy.AdtTestInterface; - -import org.eclipse.swt.graphics.Rectangle; - - -class AdtGroovyTest implements AdtTestInterface { - - /** Returns a true if the argument is LinearLayout. */ - public boolean acceptDrag(String xmlName) { - if (xmlName == "LinearLayout") { - return true; - } - - return false; - } - - /** Returns a new SWT Rectangle if LinearLayout or null. */ - public Rectangle acceptDrop(String xmlName) { - if (xmlName == "LinearLayout") { - return new Rectangle(1, 2, 3, 4); - } - - return null; - } - - /** Always throw an assert. */ - public void testAssert() { - assert true == false - } - - /** - * Returns some Groovy object, in this case a map with some info and a closure. - * The caller will return this object to testGroovyObject. - */ - public Object returnGroovyObject() { - - return [ - TheInstance: this, - SomeRect: new Rectangle(1, 2, 3, 4), - SomeClosure: { int x, int y -> x + y } - ] - } - - /** Returns true if the object is the same as the one created by returnGroovyObject. */ - public boolean testGroovyObject(Object o) { - // Input argument should be a map - assert o.getClass() == LinkedHashMap - - // We expected these keys - assert o.containsKey("TheInstance") - assert o.containsKey("SomeRect") - assert o.containsKey("SomeClosure") - - // Check the values - assert o.TheInstance.is(this) // check identity, not equality - assert o.SomeRect == new Rectangle(1, 2, 3, 4) - assert o.SomeClosure != null - - // Execute the closure - assert o.SomeClosure(42, 3) == 45 - - // Everything succeeded - return true - } - -} - diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngineTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngineTest.java index f6a2ff1..d9a1a3d 100755 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngineTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngineTest.java @@ -30,37 +30,8 @@ public class RulesEngineTest extends TestCase { super.tearDown(); } - - public void testCreate() { -// DISABLED to fix the build. EasyMock dependency not found on the build server, -// will be fixed in next CL. -// // Creating a RulesEngine from a given project should ask for the location -// // of the projects' /gscripts folder. -// IProject projectMock = EasyMock.createMock(IProject.class); -// EasyMock.expect(projectMock.findMember(RulesEngine.FD_GSCRIPTS)).andReturn(null); -// EasyMock.replay(projectMock); -// -// RulesEngine r = new RulesEngine(projectMock); -// assertNotNull(r); -// -// EasyMock.verify(projectMock); + public void testDummy() { + // Here to avoid warning that RulesEngineTest is empty } - public void testCallGetDisplayName() { -// DISABLED to fix the build. EasyMock dependency not found on the build server, -// will be fixed in next CL. -// IProject projectMock = EasyMock.createMock(IProject.class); -// EasyMock.expect(projectMock.findMember(RulesEngine.FD_GSCRIPTS)).andReturn(null); -// EasyMock.expect(projectMock.getName()).andReturn("unit-test"); -// EasyMock.replay(projectMock); -// -// RulesEngine r = new RulesEngine(projectMock); -// -// ViewElementDescriptor ved = new ViewElementDescriptor("view", SdkConstants.CLASS_VIEW); -// UiViewElementNode uiv = new UiViewElementNode(ved); -// -// // TODO: this test is not ready. We need a way to override -// // String result = r.callGetDisplayName(uiv); -// // assertEquals("com.example.MyJavaClass", result); - } } diff --git a/eclipse/scripts/build_server.sh b/eclipse/scripts/build_server.sh index aa63b18..12e4472 100755 --- a/eclipse/scripts/build_server.sh +++ b/eclipse/scripts/build_server.sh @@ -61,8 +61,8 @@ function check_params() { function build_libs() { MAKE_OPT="-j8" - echo "*** Building: make $MAKE_OPT dx ping ddms androidprefs groovy-all-1.7.0 layoutlib layoutlib_api layoutlib_utils ninepatch sdklib sdkuilib" - make $MAKE_OPT dx ping ddms androidprefs groovy-all-1.7.0 layoutlib layoutlib_api layoutlib_utils ninepatch sdklib sdkuilib + echo "*** Building: make $MAKE_OPT dx ping ddms androidprefs layoutlib layoutlib_api layoutlib_utils ninepatch sdklib sdkuilib" + make $MAKE_OPT dx ping ddms androidprefs layoutlib layoutlib_api layoutlib_utils ninepatch sdklib sdkuilib } function build_plugin { diff --git a/eclipse/scripts/create_adt_symlinks.sh b/eclipse/scripts/create_adt_symlinks.sh index 4fd99fb..fef0761 100755 --- a/eclipse/scripts/create_adt_symlinks.sh +++ b/eclipse/scripts/create_adt_symlinks.sh @@ -31,7 +31,6 @@ if [ "$HOST" == "Linux" ]; then done ln -svf $BACK/out/host/linux-x86/framework/kxml2-2.3.0.jar "$DEST/" ln -svf $BACK/out/host/linux-x86/framework/commons-compress-1.0.jar "$DEST/" - ln -svf $BACK/out/host/linux-x86/framework/groovy-all-1.7.0.jar "$DEST/" elif [ "$HOST" == "Darwin" ]; then for LIB in $LIBS; do @@ -39,7 +38,6 @@ elif [ "$HOST" == "Darwin" ]; then done ln -svf $BACK/out/host/darwin-x86/framework/kxml2-2.3.0.jar "$DEST/" ln -svf $BACK/out/host/darwin-x86/framework/commons-compress-1.0.jar "$DEST/" - ln -svf $BACK/out/host/darwin-x86/framework/groovy-all-1.7.0.jar "$DEST/" elif [ "${HOST:0:6}" == "CYGWIN" ]; then for LIB in $LIBS; do @@ -54,10 +52,6 @@ elif [ "${HOST:0:6}" == "CYGWIN" ]; then cp -v "prebuilt/common/commons-compress/commons-compress-1.0.jar" "$DEST/" fi - if [ ! -f "$DEST/groovy-all-1.7.0.jar" ]; then - cp -v "prebuilt/common/groovy/groovy-all-1.7.0.jar" "$DEST/" - fi - chmod -v a+rx "$DEST"/*.jar else echo "Unsupported platform ($HOST). Nothing done." diff --git a/eclipse/scripts/create_test_symlinks.sh b/eclipse/scripts/create_test_symlinks.sh index 9a9849a..dca9bf3 100755 --- a/eclipse/scripts/create_test_symlinks.sh +++ b/eclipse/scripts/create_test_symlinks.sh @@ -49,7 +49,6 @@ if [ "$HOST" == "Linux" ]; then done ln -svf $BACK/out/host/linux-x86/framework/kxml2-2.3.0.jar "$DEST/" ln -svf $BACK/out/host/linux-x86/framework/layoutlib.jar "$DEST/" - ln -svf $BACK/out/host/linux-x86/framework/groovy-all-1.7.0.jar "$DEST/" elif [ "$HOST" == "Darwin" ]; then for LIB in $LIBS; do @@ -57,7 +56,6 @@ elif [ "$HOST" == "Darwin" ]; then done ln -svf $BACK/out/host/darwin-x86/framework/kxml2-2.3.0.jar "$DEST/" ln -svf $BACK/out/host/darwin-x86/framework/layoutlib.jar "$DEST/" - ln -svf $BACK/out/host/darwin-x86/framework/groovy-all-1.7.0.jar "$DEST/" elif [ "${HOST:0:6}" == "CYGWIN" ]; then for LIB in $LIBS; do @@ -67,10 +65,6 @@ elif [ "${HOST:0:6}" == "CYGWIN" ]; then cp -v "prebuilt/common/kxml2/kxml2-2.3.0.jar" "$DEST/" fi - if [ ! -f "$DEST/groovy-all-1.7.0.jar" ]; then - cp -v "prebuilt/common/groovy/groovy-all-1.7.0.jar" "$DEST/" - fi - LIBS="layoutlib.jar" NEED_MAKE="yes" for LIB in $LIBS ; do diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java index 4fe574b..19cad00 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java @@ -61,6 +61,7 @@ public class ProjectProperties { private final static String PROPERTY_LIB_REF_REGEX = "android.library.reference.\\d+"; public final static String PROPERTY_PROGUARD_CONFIG = "proguard.config"; + public final static String PROPERTY_RULES_PATH = "layoutrules.jars"; public final static String PROPERTY_SDK = "sdk.dir"; // LEGACY - Kept so that we can actually remove it from local.properties. @@ -87,7 +88,8 @@ public class ProjectProperties { }, null), DEFAULT(SdkConstants.FN_DEFAULT_PROPERTIES, DEFAULT_HEADER, new String[] { PROPERTY_TARGET, PROPERTY_LIBRARY, PROPERTY_LIB_REF_REGEX, - PROPERTY_KEY_STORE, PROPERTY_KEY_ALIAS, PROPERTY_PROGUARD_CONFIG + PROPERTY_KEY_STORE, PROPERTY_KEY_ALIAS, PROPERTY_PROGUARD_CONFIG, + PROPERTY_RULES_PATH }, null), LOCAL(SdkConstants.FN_LOCAL_PROPERTIES, LOCAL_HEADER, new String[] { PROPERTY_SDK |