aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/.classpath1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/about.html3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/build.properties1
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IViewRule.java11
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/BaseLayout.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ExplodedRenderingHelper.java2
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java6
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java2
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java8
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeFactory.java2
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java4
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java380
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/.classpath1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/build.properties1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java11
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/GroovyTestsSuite.java46
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java3
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/TestGroovy.java175
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/compile_error.groovy34
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/invalid_interface.groovy24
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/groovytests/simple_test.groovy85
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngineTest.java33
-rwxr-xr-xeclipse/scripts/build_server.sh4
-rwxr-xr-xeclipse/scripts/create_adt_symlinks.sh6
-rwxr-xr-xeclipse/scripts/create_test_symlinks.sh6
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java4
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