Skip to Content.
Sympa Menu

notify-dpml - svn commit: r1772 - in development/laboratory/ide: . idea-plugin idea-plugin/etc idea-plugin/magic idea-plugin/magic/etc idea-plugin/magic/etc/main idea-plugin/magic/etc/main/net idea-plugin/magic/etc/main/net/dpml idea-plugin/magic/etc/main/net/dpml/ide idea-plugin/magic/etc/main/net/dpml/ide/idea idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin/magic idea-plugin/magic/src idea-plugin/magic/src/main idea-plugin/magic/src/main/net idea-plugin/magic/src/main/net/dpml idea-plugin/magic/src/main/net/dpml/ide idea-plugin/magic/src/main/net/dpml/ide/idea idea-plugin/magic/src/main/net/dpml/ide/idea/plugin idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic

notify-dpml AT lists.ibiblio.org

Subject: DPML Notify

List archive

Chronological Thread  
  • From: herzog AT raffael.ch
  • To: notify-dpml AT lists.ibiblio.org
  • Subject: svn commit: r1772 - in development/laboratory/ide: . idea-plugin idea-plugin/etc idea-plugin/magic idea-plugin/magic/etc idea-plugin/magic/etc/main idea-plugin/magic/etc/main/net idea-plugin/magic/etc/main/net/dpml idea-plugin/magic/etc/main/net/dpml/ide idea-plugin/magic/etc/main/net/dpml/ide/idea idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin/magic idea-plugin/magic/src idea-plugin/magic/src/main idea-plugin/magic/src/main/net idea-plugin/magic/src/main/net/dpml idea-plugin/magic/src/main/net/dpml/ide idea-plugin/magic/src/main/net/dpml/ide/idea idea-plugin/magic/src/main/net/dpml/ide/idea/plugin idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic
  • Date: Sun, 13 Feb 2005 16:08:45 +0100

Author: herzog AT raffael.ch
Date: Sun Feb 13 16:08:43 2005
New Revision: 1772

Added:
development/laboratory/ide/
development/laboratory/ide/idea-plugin/ (props changed)
development/laboratory/ide/idea-plugin/README
development/laboratory/ide/idea-plugin/build.xml
development/laboratory/ide/idea-plugin/etc/
development/laboratory/ide/idea-plugin/etc/plugin.xml
development/laboratory/ide/idea-plugin/index.xml
development/laboratory/ide/idea-plugin/magic/ (props changed)
development/laboratory/ide/idea-plugin/magic/build.xml
development/laboratory/ide/idea-plugin/magic/etc/
development/laboratory/ide/idea-plugin/magic/etc/main/
development/laboratory/ide/idea-plugin/magic/etc/main/net/
development/laboratory/ide/idea-plugin/magic/etc/main/net/dpml/
development/laboratory/ide/idea-plugin/magic/etc/main/net/dpml/ide/
development/laboratory/ide/idea-plugin/magic/etc/main/net/dpml/ide/idea/

development/laboratory/ide/idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin/

development/laboratory/ide/idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin/magic/

development/laboratory/ide/idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin/magic/magic-icon.png
(contents, props changed)
development/laboratory/ide/idea-plugin/magic/src/
development/laboratory/ide/idea-plugin/magic/src/main/
development/laboratory/ide/idea-plugin/magic/src/main/net/
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Configuration.java

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Dependency.java

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/DependentObject.java

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicPlugin.java

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicProject.java

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicResource.java

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Message.java

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/ProjectBuilder.java

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/SettingsForm.form

development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/SettingsForm.java
Log:
Initial revision. Adding a first prototype of a DPML plugin for idea.


Added: development/laboratory/ide/idea-plugin/README
==============================================================================
--- (empty file)
+++ development/laboratory/ide/idea-plugin/README Sun Feb 13 16:08:43
2005
@@ -0,0 +1,64 @@
+This is a first prototype of a plugin for integrating DPML into the
+IntelliJ IDEA IDE.
+
+
+INSTALLATION
+
+You need Magic installed und operational.
+
+To initially set up the repository, type
+
+ $ ant -Didea.home=/path/to/idea setup
+
+This will copy some files from your local IDEA installation into the DPML
+cache.
+
+Then build the plugin using
+
+ $ ant plugin
+
+The plugin will be located in target/deliverables/dpml-idea.zip. Unzip
+this file to your plugin directory, restart IDEA, the plugin should be
+installed now.
+
+Optionally, you can also try
+
+ $ ant plugin:install
+
+This, however, has only been tested on UNIX systems.
+
+I tested the plugin with IDEA 4.5.3.
+
+
+TODO
+
+FIXME: todo
+
+
+CONTACT
+
+If you find any bugs, have any suggestions, or just want to praise me for
+my great work, feel free to contact me by e-mail:
+
+ Raffael Herzog <herzog AT raffael.ch>
+
+or ask in the DPML mailing lists.
+
+
+LEGAL
+
+Just do be sure :)
+
+ Copyright 2005 Raffael Herzog
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.

Added: development/laboratory/ide/idea-plugin/build.xml
==============================================================================
--- (empty file)
+++ development/laboratory/ide/idea-plugin/build.xml Sun Feb 13 16:08:43
2005
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2005 Raffael Herzog
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="dpml-idea-plugin" default="default" basedir="."
+ xmlns:transit="antlib:net.dpml.transit">
+
+ <transit:import uri="artifact:template:dpml/magic/reactor"/>
+
+ <target name="cleanall" depends="clean">
+ <delete dir="target"/>
+ </target>
+
+ <target name="plugin" depends="package">
+ <mkdir dir="target/deliverables/jars"/>
+ <jar jarfile="target/deliverables/jars/plugin.jar">
+ <zipfileset prefix="META-INF" dir="etc">
+ <include name="plugin.xml"/>
+ </zipfileset>
+ </jar>
+ <zip zipfile="target/deliverables/dpml-idea.zip">
+ <zipfileset prefix="dpml-idea/lib"
dir="target/deliverables/jars">
+ <include name="*.jar"/>
+ </zipfileset>
+ <zipfileset prefix="dpml-idea/lib"
dir="magic/target/deliverables/jars/">
+ <include name="*.jar"/>
+ </zipfileset>
+ <zipfileset prefix="dpml-idea/lib"
dir="${dpml.cache}/LOCAL/idea/jars">
+ <include name="forms_rt.jar"/>
+ </zipfileset>
+ <zipfileset prefix="dpml-idea/lib"
dir="${dpml.cache}/commons-lang/jars">
+ <include name="commons-lang-2.0.jar"/>
+ </zipfileset>
+ <zipfileset prefix="dpml-idea/lib"
dir="${dpml.cache}/commons-digester/jars">
+ <include name="commons-digester-1.6.jar"/>
+ </zipfileset>
+ <zipfileset prefix="dpml-idea/lib"
dir="${dpml.cache}/commons-beanutils/jars">
+ <include name="commons-beanutils-1.6.jar"/>
+ </zipfileset>
+ <zipfileset prefix="dpml-idea/lib"
dir="${dpml.cache}/commons-collections/jars">
+ <include name="commons-collections-2.1.jar"/>
+ </zipfileset>
+ <zipfileset prefix="dpml-idea/lib"
dir="${dpml.cache}/commons-logging/jars">
+ <include name="commons-logging-1.0.3.jar"/>
+ </zipfileset>
+ <zipfileset prefix="dpml-idea/lib"
dir="${dpml.cache}/dpml/transit/jars">
+ <include name="dpml-transit-main-SNAPSHOT.jar"/>
+ </zipfileset>
+ </zip>
+ </target>
+
+ <target name="plugin:install" depends="plugin">
+ <unzip src="target/deliverables/dpml-idea.zip"
dest="${user.home}/.IntelliJIdea/config/plugins"/>
+ </target>
+
+ <target name="setup">
+ <mkdir dir="${dpml.cache}/LOCAL/idea/jars"/>
+ <copy file="${idea.home}/lib/openapi.jar"
tofile="${dpml.cache}/LOCAL/idea/jars/openapi-LOCAL.jar"/>
+ <copy file="${idea.home}/redist/forms_rt.jar"
tofile="${dpml.cache}/LOCAL/idea/jars/forms_rt-LOCAL.jar"/>
+ </target>
+
+</project>

Added: development/laboratory/ide/idea-plugin/etc/plugin.xml
==============================================================================
--- (empty file)
+++ development/laboratory/ide/idea-plugin/etc/plugin.xml Sun Feb 13
16:08:43 2005
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2005 Raffael Herzog
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<idea-plugin>
+
+ <name>DPML</name>
+ <description>
+ The DPML plugin provides functionality for working with DPML
products.
+ Currently, it only provides support for synchronizing IDEA projects
with
+ Magic's index.xml files.
+ </description>
+ <version>SNAPSHOT</version>
+ <vendor url="http://www.dpml.net/";>DPML</vendor>
+ <idea-version min="4.0" max="4.5.x"/>
+
+ <application-components/>
+
+ <project-components>
+ <component>
+
<implementation-class>net.dpml.ide.idea.plugin.magic.MagicPlugin</implementation-class>
+ </component>
+ </project-components>
+
+</idea-plugin>
\ No newline at end of file

Added: development/laboratory/ide/idea-plugin/index.xml
==============================================================================
--- (empty file)
+++ development/laboratory/ide/idea-plugin/index.xml Sun Feb 13 16:08:43
2005
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2005 Raffael Herzog
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<index key="dpml-idea-plugin">
+
+ <project basedir="magic">
+ <info>
+ <group>dpml/idea-plugin</group>
+ <name>dpml-idea-magic</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <type>jar</type>
+ </info>
+ <dependencies>
+ <include key="openapi" runtime="false"/>
+ <include key="forms_rt"/>
+ <include key="jdom" runtime="false"/>
+ <include key="commons-lang"/>
+ <include key="commons-digester"/>
+ <include key="dpml-transit-main"/>
+ </dependencies>
+ </project>
+
+ <resource>
+ <info>
+ <group>LOCAL/idea</group>
+ <name>openapi</name>
+ <version>LOCAL</version>
+ <type>jar</type>
+ </info>
+ </resource>
+
+ <resource>
+ <info>
+ <group>LOCAL/idea</group>
+ <name>forms_rt</name>
+ <version>LOCAL</version>
+ <type>jar</type>
+ </info>
+ </resource>
+
+ <resource>
+ <info>
+ <group>jdom</group>
+ <name>jdom</name>
+ <version>1.0</version>
+ <type>jar</type>
+ </info>
+ </resource>
+
+ <resource>
+ <info>
+ <group>commons-lang</group>
+ <name>commons-lang</name>
+ <version>2.0</version>
+ <type>jar</type>
+ </info>
+ </resource>
+
+ <resource>
+ <info>
+ <group>commons-digester</group>
+ <name>commons-digester</name>
+ <version>1.6</version>
+ <type>jar</type>
+ </info>
+ <dependencies>
+ <include key="commons-beanutils"/>
+ <include key="commons-collections"/>
+ <include key="commons-logging"/>
+ </dependencies>
+ </resource>
+
+ <resource>
+ <info>
+ <group>commons-beanutils</group>
+ <name>commons-beanutils</name>
+ <version>1.6</version>
+ <type>jar</type>
+ </info>
+ <dependencies>
+ <include key="commons-logging"/>
+ </dependencies>
+ </resource>
+
+ <resource>
+ <info>
+ <group>commons-collections</group>
+ <name>commons-collections</name>
+ <version>2.1</version>
+ <type>jar</type>
+ </info>
+ </resource>
+
+ <resource>
+ <info>
+ <group>commons-logging</group>
+ <name>commons-logging</name>
+ <version>1.0.3</version>
+ <type>jar</type>
+ </info>
+ </resource>
+
+ <resource>
+ <info>
+ <group>dpml/transit</group>
+ <name>dpml-transit-main</name>
+ <version>SNAPSHOT</version>
+ <type>jar</type>
+ </info>
+ </resource>
+
+</index>

Added: development/laboratory/ide/idea-plugin/magic/build.xml
==============================================================================
--- (empty file)
+++ development/laboratory/ide/idea-plugin/magic/build.xml Sun Feb 13
16:08:43 2005
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2005 Raffael Herzog
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="dpml-idea-magic" default="install" basedir="."
+ xmlns:transit="antlib:net.dpml.transit">
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+ <target name="plugin">
+ <echo>${dpml.cache}</echo>
+ </target>
+
+</project>

Added:
development/laboratory/ide/idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin/magic/magic-icon.png
==============================================================================
Binary file. No diff available.

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Configuration.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Configuration.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+import java.io.File;
+
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+
+/**
+ * This class represents the (project level) configuration of the plugin. It
also handles serializing and deserializing
+ * the configuation to/from the project file.
+ *
+ * @author <a href="mailto:herzog AT raffael.ch";>Raffael Herzog</a>
+ *
+ * @see ConfigurationHolder for the configuration values.
+ */
+public class Configuration {
+
+ private final ConfigurationHolder holder = new ConfigurationHolder();
+
+ /**
+ * Create a new configuration with default values.
+ */
+ public Configuration() {
+ }
+
+ /**
+ * Create a new configuration copying the values of the given
configuration.
+ *
+ * @param c The configuration to copy the values from.
+ *
+ * @see #copy(Configuration)
+ */
+ public Configuration(Configuration c) {
+ this();
+ copy(c);
+ }
+
+ /**
+ * Return the hash code based on all configuration values.
+ *
+ * @return The hash code.
+ *
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ return new HashCodeBuilder()
+ .append(holder.syncWithMagic)
+ .append(holder.strictSyncing)
+ .append(holder.recursiveDependencies)
+ .append(holder.jUnitLibrary)
+ .append(holder.cacheDir)
+ .toHashCode();
+ }
+
+ /**
+ * Returns true if the all configuration values of the given
configuration are equal to this configuration.
+ *
+ * @param o The other configuration.
+ *
+ * @return True, if the two configurations are equal.
+ *
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object o) {
+ if ( o instanceof Configuration ) {
+ ConfigurationHolder h = ((Configuration)o).holder;
+ return new EqualsBuilder()
+ .append(holder.syncWithMagic, h.syncWithMagic)
+ .append(holder.strictSyncing, h.strictSyncing)
+ .append(holder.recursiveDependencies,
h.recursiveDependencies)
+ .append(holder.jUnitLibrary, h.jUnitLibrary)
+ .append(holder.cacheDir, h.cacheDir)
+ .isEquals();
+ }
+ else {
+ return false;
+ }
+ }
+
+
+
+ /*
+ * externalization
+ */
+
+ /**
+ * Read the configuration from a JDOM tree.
+ *
+ * @param element The parent JDOM element.
+ *
+ * @throws InvalidDataException
+ */
+ void readExternal(org.jdom.Element element) throws InvalidDataException {
+ DefaultJDOMExternalizer.readExternal(holder, element);
+ }
+
+ /**
+ * Serialize the configuration into a JDOM tree.
+ *
+ * @param element The parent JDOM element.
+ *
+ * @throws WriteExternalException
+ */
+ void writeExternal(org.jdom.Element element) throws
WriteExternalException {
+ DefaultJDOMExternalizer.writeExternal(holder, element);
+ }
+
+
+
+ /*
+ * getters/setters
+ */
+
+ public boolean getSyncWithMagic() {
+ return holder.syncWithMagic;
+ }
+
+ public void setSyncWithMagic(boolean magicProject) {
+ holder.syncWithMagic = magicProject;
+ }
+
+ public boolean getStrictSyncing() {
+ return holder.strictSyncing;
+ }
+
+ public void setStrictSyncing(boolean strictSyncing) {
+ holder.strictSyncing = strictSyncing;
+ }
+
+ public boolean getRecursiveDependencies() {
+ return holder.recursiveDependencies;
+ }
+
+ public void setRecursiveDependencies(boolean recursiveDependencies) {
+ holder.recursiveDependencies = recursiveDependencies;
+ }
+
+ public String getJUnitLibrary() {
+ return holder.jUnitLibrary;
+ }
+
+ public void setJUnitLibrary(String jUnitLibrary) {
+ holder.jUnitLibrary = jUnitLibrary;
+ }
+
+ public String getCacheDir() {
+ if ( holder.cacheDir == null ) {
+ return new File(System.getProperty("user.home"),
".dpml/cache").toString();
+ }
+ else {
+ return holder.cacheDir;
+ }
+ }
+
+ public void setCacheDir(String cacheDir) {
+ holder.cacheDir = cacheDir;
+ }
+
+ public boolean hasCacheDir() {
+ return holder.cacheDir != null;
+ }
+
+ /**
+ * Get the default cache directory of DPML.
+ * <p>
+ * <strong>FIXME: Use the DPML_HOME and DMPL_CACHE environment
variables</strong>
+ *
+ * @return The default cache directory.
+ */
+ public String getDefaultCacheDir() {
+ return new File(System.getProperty("user.home"),
".dpml/cache").toString();
+ }
+
+
+ /*
+ * configuration copying
+ */
+
+ /**
+ * Copy the the values of the given configuration into this one.
+ *
+ * @param c The configuration to copy the values from.
+ */
+ public void copy(Configuration c) {
+ holder.syncWithMagic = c.holder.syncWithMagic;
+ holder.strictSyncing = c.holder.strictSyncing;
+ holder.recursiveDependencies = c.holder.recursiveDependencies;
+ holder.jUnitLibrary = c.holder.jUnitLibrary;
+ holder.cacheDir = c.holder.cacheDir;
+ }
+
+
+
+ /*
+ * inner classes
+ */
+
+ /**
+ * This class is used to store the actual configuration values. I made
this to be able to use the default IDEA tools
+ * to (de)serialize the configuration, which require the fields to be
public, while still keeping control over the
+ * values through get/set methods.
+ */
+ private final static class ConfigurationHolder {
+ /**
+ * If true, this project is synchronized with Magic index.xml files.
Currently, this option doesn't make much
+ * sense, but it will later, when listening to index.xml files and
automatic synchronization is enabled. :)
+ */
+ public boolean syncWithMagic = false;
+ /**
+ * If true, synchronize strictly. If strict synchronization is
enabled, unneded dependencies or roots are
+ * removed during synchronization. If it's disabled, only missing
entries will be added.
+ */
+ public boolean strictSyncing = true;
+ /**
+ * If true, collect dependencies recursively, i.e. include
dependencies of dependencies.
+ */
+ public boolean recursiveDependencies = true;
+ /**
+ * The name of the system level library containing the JUnit
classes. Each module will depend on this.
+ */
+ public String jUnitLibrary = null;
+ /**
+ * The path to the cache directory of DPML. If null, the default
will be used (${user.home}/.dpml/cache.
+ */
+ public String cacheDir = null;
+ }
+
+}

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Dependency.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Dependency.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+/**
+ * Represents a dependency. Each {@link DependentObject} may depend on more
{@link DependentObject}s.
+ *
+ * @author <a href="mailto:herzog AT raffael.ch";>Raffael Herzog</a>
+ */
+public class Dependency {
+
+ /**
+ * The key of the dependency (as in <code>&lt;include
key="..."/&gt;)</code>.
+ */
+ private String key;
+ /**
+ * True, if it's a build dependency. Currenty ignored.
+ */
+ private boolean build = true;
+ /**
+ * True, if it's a test dependency. Currently ignored.
+ */
+ private boolean test = true;
+ /**
+ * True, if it's a runtime dependency. Currently ignored.
+ */
+ private boolean runtime = true;
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public boolean isBuild() {
+ return build;
+ }
+
+ public void setBuild(boolean build) {
+ this.build = build;
+ }
+
+ public boolean isTest() {
+ return test;
+ }
+
+ public void setTest(boolean test) {
+ this.test = test;
+ }
+
+ public boolean isRuntime() {
+ return runtime;
+ }
+
+ public void setRuntime(boolean runtime) {
+ this.runtime = runtime;
+ }
+
+ public String toString() {
+ return "Dependency["+getKey()+"; build: "+build+"; test: "+test+";
runtime: "+runtime+"]";
+ }
+
+ public int hashCode() {
+ return key.hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if ( o instanceof Dependency ) {
+ return ((Dependency)o).key.equals(key);
+ }
+ else {
+ return false;
+ }
+ }
+
+}

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/DependentObject.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/DependentObject.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Base class for dependent objects which implements the dependency tracking.
+ *
+ * @author <a href="mailto:herzog AT raffael.ch";>Raffael Herzog</a>
+ */
+public class DependentObject {
+
+ /**
+ * A set of {@link Dependency} objects.
+ */
+ private final Set dependencies = new HashSet();
+ /**
+ * An unmodifiable version of {@link dependencies} for {@link
getDependencies()}.
+ */
+ private final Set unmodifiableDependencies =
Collections.unmodifiableSet(dependencies);
+
+ /**
+ * Add a new dependency.
+ *
+ * @param dep The new dependency
+ */
+ public void addDependency(Dependency dep) {
+ dependencies.add(dep);
+ }
+
+ /**
+ * Get the dependencies.
+ *
+ * @return An unmodifiable set of {@link Dependency} objects.
+ */
+ public Set getDependencies() {
+ return unmodifiableDependencies;
+ }
+}

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicPlugin.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicPlugin.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+import java.net.URL;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+
+import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+
+import org.jdom.Element;
+
+
+/**
+ * This is the main plugin implementation class.
+ *
+ * @author <a href="mailto:herzog AT raffael.ch";>Raffael Herzog</a>
+ */
+public class MagicPlugin implements ProjectComponent, Configurable,
JDOMExternalizable {
+
+ /*
+ * constants
+ */
+
+ public static final String PLUGIN_NAME = "DPML Magic";
+
+
+
+ /*
+ * fields
+ */
+
+ /**
+ * The logger this plugin uses for logging.
+ */
+ final Logger log;
+ /**
+ * The project this plugin handles.
+ */
+ final Project project;
+ /**
+ * The plugin's configuration.
+ */
+ final Configuration config = new Configuration();
+
+ /**
+ * The icon for the settings dialog.
+ */
+ private Icon icon = null;
+
+ /**
+ * The form for the settings dialog.
+ */
+ private SettingsForm settingsForm = null;
+
+
+
+ /*
+ * constructors
+ */
+
+ /**
+ * Create a new instance of the plugin. This will be called by IDEA.
+ *
+ * @param project The plugin's project.
+ */
+ public MagicPlugin(Project project) {
+ this.log = Logger.getInstance(MagicPlugin.class.getName());
+ this.project = project;
+ }
+
+
+ /*
+ * implementation of ProjectComponent
+ */
+
+ /**
+ * Called by IDEA after the project has been openend.
+ */
+ public void projectOpened() {
+ }
+
+ /**
+ * Called by IDEA after the project has been closed.
+ */
+ public void projectClosed() {
+ }
+
+ /**
+ * The name of the plugin.
+ *
+ * @return The name of the plugin.
+ */
+ public String getComponentName() {
+ return "MagicPlugin";
+ }
+
+ /**
+ * Called by IDEA to initialize the plugin.
+ */
+ public void initComponent() {
+ }
+
+ /**
+ * Called by IDEA to dispose the plugin.
+ */
+ public void disposeComponent() {
+ }
+
+
+
+ /*
+ * implementation of Configurable
+ */
+
+ /**
+ * Get name of the plugin displayed to the user.
+ *
+ * @return The display name.
+ */
+ public String getDisplayName() {
+ return PLUGIN_NAME;
+ }
+
+ /**
+ * Get the icon of the plugin.
+ *
+ * @return The icon of the plugin.
+ */
+ public Icon getIcon() {
+ if ( icon == null ) {
+ URL iconRes =
MagicPlugin.class.getResource("/net/dpml/ide/idea/plugin/magic/magic-icon.png");
+ if ( iconRes != null ) {
+ icon = new ImageIcon(iconRes);
+ }
+ }
+ return icon;
+ }
+
+ /**
+ * Get the help topic of the plugin. This currently always returns
<code>null</code>.
+ *
+ * @return <code>null</code>
+ */
+ public String getHelpTopic() {
+ return null;
+ }
+
+ /**
+ * Create the GUI component for the settings panel.
+ *
+ * @return The GUI component for the settings panel.
+ */
+ public JComponent createComponent() {
+ if (settingsForm == null) {
+ settingsForm = new SettingsForm(project, log, new
Configuration(config));
+ }
+ else {
+ settingsForm.setConfig(new Configuration(config));
+ }
+ return settingsForm.getRootPanel();
+ }
+
+ /**
+ * Returns <code>true</code>, if the configuration in the settings panel
has been modified.
+ *
+ * @return <code>true</code>, if the configuration has been modified.
+ */
+ public boolean isModified() {
+ if (settingsForm != null) {
+ return !config.equals(settingsForm.apply());
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Called by IDEA to apply the configuration in the settings panel to
the plugin.
+ */
+ public void apply() {
+ Configuration newConfig = settingsForm.apply();
+ boolean apply;
+ if ( !newConfig.equals(config) ) {
+ int answer = Messages.showOkCancelDialog(project,
+ "This will rebuild your
project.\nAre you sure you want to continue?",
+ PLUGIN_NAME,
+
Messages.getWarningIcon());
+ apply = (answer == 0);
+ }
+ else {
+ apply = false;
+ }
+ if (apply) {
+ config.copy(newConfig);
+ ProjectBuilder.rebuildProject(project, log, config);
+ }
+ else {
+ reset();
+ }
+ }
+
+ /**
+ * Called by IDEA to reset the configuration in the settings panel to
the plugin's current configuration.
+ */
+ public void reset() {
+ settingsForm.setConfig(new Configuration(config));
+ }
+
+ /**
+ * Called by IDEA to dispose any UI resources.
+ */
+ public void disposeUIResources() {
+ settingsForm = null;
+ }
+
+
+
+ /*
+ * implementation of JDOMExternalizable
+ */
+
+ /**
+ * Called by IDEA to read the configuration from the project file.
+ *
+ * @param element The root JDOM element.
+ * @throws InvalidDataException
+ */
+ public void readExternal(Element element) throws InvalidDataException {
+ config.readExternal(element);
+ }
+
+ /**
+ * Called by IDEA to write the configuration to the project file.
+ *
+ * @param element The root JDOM element.
+ * @throws WriteExternalException
+ */
+ public void writeExternal(Element element) throws WriteExternalException
{
+ config.writeExternal(element);
+ }
+
+}

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicProject.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicProject.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+import java.io.File;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+
+/**
+ * Represents a Magic project.
+ *
+ * @author <a href="mailto:herzog AT raffael.ch";>Raffael Herzog</a>
+ */
+public class MagicProject extends DependentObject {
+
+ /**
+ * The path of the index file the project is declared in.
+ */
+ private String indexPath;
+ /**
+ * The base directory of the project relative to the index file.
+ */
+ private String basedir = ".";
+ /**
+ * The group of the artifact.
+ */
+ private String group;
+ /**
+ * The name of the artifact.
+ */
+ private String name;
+
+ public String getIndexPath() {
+ return indexPath;
+ }
+
+ public void setIndexPath(String indexFile) {
+ this.indexPath = indexFile;
+ }
+
+ public String getBasedir() {
+ return basedir;
+ }
+
+ public void setBasedir(String basedir) {
+ this.basedir = basedir;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getModuleName() {
+ return new File(basedir).getName();
+ //return group.replace('/', '.')+"."+name;
+ }
+
+ public String toString() {
+ return "Project[" + group + ":" + name + "@" + basedir + "]";
+ }
+
+ /**
+ * Returns a hash code based on the artifact group and name.
+ *
+ * @return The hash code.
+ */
+ public int hashCode() {
+ return new HashCodeBuilder()
+ .append(group)
+ .append(name)
+ .toHashCode();
+ }
+
+ /**
+ * Returns true, if the group and the name of the given project are
equal.
+ *
+ * @param o The other object.
+ *
+ * @return <code>true</code>, if the goup and the name of the other
project are equal.
+ */
+ public boolean equals(Object o) {
+ if ( o instanceof MagicProject ) {
+ MagicProject p = (MagicProject)o;
+ return new EqualsBuilder()
+ .append(group, p.group)
+ .append(name, p.name)
+ .isEquals();
+ }
+ else {
+ return false;
+ }
+ }
+
+}

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicResource.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/MagicResource.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+
+/**
+ * Represents a Magic resource specification.
+ *
+ * @author <a href="mailto:herzog AT raffael.ch";>Raffael Herzog</a>
+ */
+public class MagicResource extends DependentObject {
+
+ /**
+ * The group of the artifact.
+ */
+ private String group;
+ /**
+ * The name of the artifact.
+ */
+ private String name;
+ /**
+ * The version of the artifact.
+ */
+ private String version;
+ /**
+ * The type of the artifact.
+ */
+ private String type = "jar";
+
+ public String getGroup() {
+ return group;
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getLibraryName() {
+ return getGroup().replace('/',
'.')+"."+getName()+"."+getType()+"#"+getVersion();
+ }
+
+ public String toString() {
+ return "Resource[" + group + ":" + name + "#" + version + "]";
+ }
+
+ /**
+ * Returns a hash code based on the artifact group, name and version.
+ *
+ * @return The hash code.
+ */
+ public int hashCode() {
+ return new HashCodeBuilder()
+ .append(group)
+ .append(name)
+ .append(version)
+ .toHashCode();
+ }
+
+ /**
+ * Returns <code>true</code>, if the other resource's group, name and
version are equal.
+ *
+ * @param o The other resource.
+ *
+ * @return <code>true</code> if the resources are equal.
+ */
+ public boolean equals(Object o) {
+ if ( o instanceof MagicResource ) {
+ MagicResource r = (MagicResource)o;
+ return new EqualsBuilder()
+ .append(group, r.group)
+ .append(name, r.name)
+ .append(version, r.version)
+ .isEquals();
+ }
+ else {
+ return false;
+ }
+ }
+
+}

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Message.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/Message.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+/**
+ * Used to store messages collected during project rebuild. This will be
used to display a nice dialog showing all the
+ * messages.
+ *
+ * @author <a href="mailto:herzog AT raffael.ch";>Raffael Herzog</a>
+ */
+public class Message {
+
+ /**
+ * Constant for the message class <em>Info</em>.
+ */
+ public final static int MSG_INFO = 1;
+ /**
+ * Constant for the message class <em>Warning</em>.
+ */
+ public final static int MSG_WARNING = 2;
+ /**
+ * Constant for the message class <em>Error</em>.
+ */
+ public final static int MSG_ERROR = 3;
+
+ /**
+ * The message class.
+ */
+ private int type = MSG_INFO;
+ /**
+ * The message string.
+ */
+ private String message;
+
+ // FIXME: more data? exceptions?
+
+
+ /*
+ * constructors
+ */
+
+ public Message(String message) {
+ this(MSG_INFO, message);
+ }
+
+ public Message(int type, String message) {
+ this.type = type;
+ this.message = message;
+ }
+
+
+
+ /*
+ * getters and setters
+ */
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+}

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/ProjectBuilder.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/ProjectBuilder.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,1242 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleCircularDependencyException;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.roots.ModuleOrderEntry;
+import com.intellij.openapi.roots.LibraryOrderEntry;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.roots.libraries.LibraryTableUtil;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import org.apache.commons.digester.AbstractObjectCreationFactory;
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.SetNestedPropertiesRule;
+import org.apache.commons.lang.ObjectUtils;
+
+import net.dpml.transit.artifact.Artifact;
+
+/**
+ * The main workhorse. This object keeps the state of a project rebuild and
contains all the code.
+ *
+ * @author <a href="mailto:herzog AT raffael.ch";>Raffael Herzog</a>
+ */
+public class ProjectBuilder {
+
+ /**
+ * Set this to <true>true</true>, if you want the contents of the parsed
index.xml files to be dumped after
+ * parsing. The dump will be logged at level <em>info</em>.
+ */
+ public static final boolean DUMP = true;
+
+ private final Project project;
+ private final Logger log;
+ private final Configuration config;
+ private final ModuleManager moduleManager;
+ private ModifiableModuleModel model = null;
+ private LibraryTable.ModifiableModel libraryModel = null;
+
+ /**
+ * A list of {@link Message} objects collected during rebuild.
+ */
+ private final List messages = new LinkedList();
+
+ /**
+ * A list of index.xml files found during scan.
+ */
+ private final List indexFiles = new ArrayList();
+ /**
+ * A map of base paths mapped to module files. This will be used to map
Magic projects to IDEA modules (the module
+ * file in the base directory of the Magic project will be used).
+ */
+ private final Map moduleFiles = new HashMap();
+ /**
+ * A set of parsed index.xml files. Used to avoid duplicate parsing due
to multiple or circular imports.
+ */
+ private final Set parsedFiles = new HashSet();
+
+ /**
+ * A map of magic projects keyed by their names.
+ */
+ private final Map magicProjects = new HashMap();
+ /**
+ * A map of magic resources keyed by their names.
+ */
+ private final Map magicResources = new HashMap();
+ /**
+ * A map of resolved dependencies (projects or resources) keyed by their
keys.
+ */
+ private final Map resolvedObjects = new HashMap();
+
+ /**
+ * If some exception occurred outside the working thread, it will be
stored here for later retrieval.
+ */
+ private Throwable exception;
+
+ /**
+ * The path of the index file currently being processed. Used by the
object factory in #{link collectDependencies(ProgressIndicator, File)}.
+ */
+ private String currentIndexPath;
+
+ /**
+ * Create a new project builder. Each project builder can only be used
<em>once</em>!
+ *
+ * @param project The IDEA project to be rebuilt.
+ * @param log The logger used for logging.
+ * @param config The configuration.
+ */
+ public ProjectBuilder(Project project, Logger log, Configuration config)
{
+ this.project = project;
+ this.log = log;
+ this.config = config;
+ moduleManager = ModuleManager.getInstance(project);
+ }
+
+ /**
+ * Utility method to rebuild an IDEA projects it takes care that a
separate working thread will be used, the
+ * progress indicator will be displayed and all the other GUI stuff.
+ *
+ * @param project The IDEA project to be rebuilt.
+ * @param log The logger used for logging.
+ * @param config The configuration.
+ *
+ * @return <code>true</code>, if rebuilding the project was successful.
+ */
+ public static boolean rebuildProject(final Project project, final Logger
log, final Configuration config) {
+ log.info("Rebuilding project...");
+ Throwable exception = null;
+ final Application app = ApplicationManager.getApplication();
+ final ProjectBuilder builder = new ProjectBuilder(project, log,
config);
+ try {
+ app.runProcessWithProgressSynchronously(new Runnable() {
+ public void run() {
+ ProgressManager progressManager =
ProgressManager.getInstance();
+ ProgressIndicator progress =
progressManager.getProgressIndicator();
+ progress.start();
+ try {
+ builder.scanFiles(progress);
+ builder.collectDependencies(progress);
+ builder.applyDependencies(progress);
+ }
+ catch ( IOException exc ) {
+ // will be handled below
+ }
+ catch ( SAXException exc ) {
+ // will be handled below
+ }
+ catch ( UnresolvedDependencyException exc ) {
+ // will be handled below
+ }
+ catch ( ModuleCircularDependencyException exc ) {
+ // will be handled below
+ }
+ finally {
+ progress.stop();
+ }
+ }
+ }, "Rebuilding Project Dependencies", true, project);
+ }
+ catch ( RuntimeException exc ) {
+ exception = exc;
+ throw exc;
+ }
+ catch ( Error exc ) {
+ exception = exc;
+ throw exc;
+ }
+ finally {
+ if ( exception == null ) {
+ exception = builder.exception;
+ }
+ if ( exception != null ) {
+ Messages.showErrorDialog(project, exception.toString(),
"Error");
+ log.info("Rebuilding project finished with error.");
+ }
+ else {
+ log.info("Rebuilding project finished successfully.");
+ }
+ }
+ return builder.exception == null;
+ }
+
+ /**
+ * Scan for index.xml and IDEA module files recursively in the IDEA
project.
+ *
+ * @param progress A progress indicator.
+ */
+ public void scanFiles(final ProgressIndicator progress) {
+ try {
+ progress.setIndeterminate(true);
+ progress.setText("Scanning Files...");
+ Module[] modules =
ModuleManager.getInstance(project).getModules();
+ for (int i = 0; i < modules.length; i++) {
+ ModuleRootManager mrm =
ModuleRootManager.getInstance(modules[i]);
+ VirtualFile[] files = mrm.getContentRoots();
+ for (int j = 0; j < files.length; j++) {
+ if
(files[j].getFileSystem().getProtocol().equals(LocalFileSystem.PROTOCOL)) {
+ log.info("Scanning " + files[j].toString());
+ FileUtil.visitFilesRecursively(new
File(files[j].getPath()), new FileUtil.FileVisitor() {
+ public int accept(File file) {
+ progress.checkCanceled();
+ if (file.isFile()) {
+ progress.setText2("Scanning directory "
+ file.getParent());
+ if (file.getName().equals("index.xml")) {
+ addMessage(Message.MSG_INFO, "Found
index file: " + file);
+ indexFiles.add(file);
+ }
+ else if (
file.getName().endsWith(".iml") ) {
+ addMessage(Message.MSG_INFO, "Found
IDEA module file: " + file);
+ String dir = file.getParent();
+ File current =
(File)moduleFiles.get(dir);
+ if ( current != null ) {
+ addMessage(Message.MSG_WARNING,
"Two module files found in directory " + dir + "; using " + current);
+ }
+ else {
+ moduleFiles.put(dir, file);
+ }
+ }
+ }
+ else if (file.isDirectory()) {
+ progress.setText2("Scanning directory "
+ file);
+ }
+ return FileUtil.FileVisitor.PROCEED;
+ }
+ });
+ }
+ else {
+ log.info("Skipping " + files[j].toString());
+ }
+ }
+ }
+ }
+ catch ( RuntimeException exc ) {
+ exception = exc;
+ throw exc;
+ }
+ catch ( Error exc ) {
+ exception = exc;
+ throw exc;
+ }
+ }
+
+ /**
+ * Iterates through all index.xml files found by {@link
#scanFiles(ProgressIndicator} and calls
+ * {@link collectDependencies(ProgressIndicator,File)} for each of them.
+ *
+ * @param progress A progress indicator.
+ * @throws SAXException
+ * @throws IOException
+ * @throws UnresolvedDependencyException
+ */
+ public void collectDependencies(ProgressIndicator progress) throws
SAXException, IOException, UnresolvedDependencyException {
+ try {
+ Iterator iter = indexFiles.iterator();
+ double currentProgress = 0;
+ double progressStep = 1.0/indexFiles.size();
+ progress.setIndeterminate(false);
+ progress.setText("Parsing index files...");
+ progress.setFraction(0);
+ while (iter.hasNext()) {
+ File f = (File) iter.next();
+ progress.setText2("Parsing file " + f + "...");
+ currentIndexPath = f.getParent().toString();
+ collectDependencies(progress, f);
+ currentProgress += progressStep;
+ progress.setFraction(currentProgress);
+ }
+
+ if ( config.getRecursiveDependencies() ) {
+ Iterator depIter = magicProjects.values().iterator();
+ while ( depIter.hasNext() ) {
+ MagicProject mp = (MagicProject)depIter.next();
+ flattenDependencies(mp);
+ }
+ }
+
+ if ( DUMP ) {
+ iter = magicProjects.values().iterator();
+ while (iter.hasNext()) {
+ MagicProject m = (MagicProject)iter.next();
+ log.info("Project: " + m.getGroup() + ":" + m.getName()
+ " (" + m.getBasedir() + ")");
+ Iterator iter2 = m.getDependencies().iterator();
+ while (iter2.hasNext()) {
+ Dependency d = (Dependency)iter2.next();
+ log.info(" Dependency: "+d.getKey()+"; build:
"+d.isBuild()+"; test: "+d.isTest()+"; runtime: "+d.isRuntime());
+ }
+ }
+ iter = magicResources.values().iterator();
+ while (iter.hasNext()) {
+ MagicResource r = (MagicResource)iter.next();
+ log.info("Resource: " + r.getGroup() + ":" + r.getName()
+ "#" + r.getVersion());
+ Iterator iter2 = r.getDependencies().iterator();
+ while (iter2.hasNext()) {
+ Dependency d = (Dependency)iter2.next();
+ log.info(" Dependency: "+d.getKey()+"; build:
"+d.isBuild()+"; test: "+d.isTest()+"; runtime: "+d.isRuntime());
+ }
+ }
+ }
+ }
+ catch ( UnresolvedDependencyException exc ) {
+ exception = exc;
+ throw exc;
+ }
+ catch ( SAXException exc ) {
+ exception = exc;
+ throw exc;
+ }
+ catch ( IOException exc ) {
+ exception = exc;
+ throw exc;
+ }
+ catch ( RuntimeException exc ) {
+ exception = exc;
+ throw exc;
+ }
+ catch ( Error exc ) {
+ exception = exc;
+ throw exc;
+ }
+ }
+
+ /**
+ * Parses a specific index.xml file for dependencies of Magic projects
and resources. This method also recursively
+ * calls itself, if &lt;import&gt; statements are found.
+ *
+ * @param progress
+ * @param file
+ * @throws IOException
+ * @throws SAXException
+ */
+ private void collectDependencies(final ProgressIndicator progress, final
File file) throws IOException, SAXException {
+ progress.checkCanceled();
+ if ( parsedFiles.contains(file) ) {
+ return;
+ }
+ if ( !file.isAbsolute() ) {
+ throw new IOException("Absolute file path expected");
+ }
+ parsedFiles.add(file);
+ SetNestedPropertiesRule snp;
+ Digester digester = new Digester();
+ digester.addFactoryCreate("index/project", new
AbstractObjectCreationFactory() {
+ public Object createObject(Attributes attributes) throws
Exception {
+ MagicProject prj = new MagicProject();
+ prj.setIndexPath(currentIndexPath);
+ return prj;
+ }
+ });
+ digester.addSetProperties("index/project");
+ snp = new SetNestedPropertiesRule();
+ snp.setAllowUnknownChildElements(true);
+ digester.addRule("index/project/info", snp);
+ digester.addSetNext("index/project", "addMagicProject");
+ digester.addObjectCreate("index/project/dependencies/include",
Dependency.class);
+ digester.addSetProperties("index/project/dependencies/include");
+ digester.addSetNext("index/project/dependencies/include",
"addDependency");
+ // match */resource instead of index/resource for compatibility with
module files
+ digester.addObjectCreate("*/resource", MagicResource.class);
+ snp = new SetNestedPropertiesRule();
+ snp.setAllowUnknownChildElements(true);
+ digester.addRule("*/resource/info", snp);
+ digester.addObjectCreate("*/resource/dependencies/include",
Dependency.class);
+ digester.addSetProperties("*/resource/dependencies/include");
+ digester.addSetNext("*/resource/dependencies/include",
"addDependency");
+ digester.addSetNext("*/resource", "addMagicResource");
+
+ digester.addFactoryCreate("*/import", new
AbstractObjectCreationFactory() {
+ public Object createObject(Attributes attributes) throws
Exception {
+ return new Object() {
+ public void doImport(String fileName, String uri) throws
IOException, SAXException {
+ if ( fileName != null ) {
+ File f = new File(fileName);
+ if ( !f.isAbsolute() ) {
+ f = new File(file.getParent(), fileName);
+ }
+ collectDependencies(progress, f);
+ }
+ else {
+ try {
+ Artifact artifact =
Artifact.createArtifact(uri);
+ collectDependencies(progress, new
File(config.getCacheDir(), artifact.getPath()));
+ }
+ catch ( URISyntaxException exc ) {
+ IOException t = new IOException("Invalid URI
syntax");
+ t.initCause(exc);
+ throw t;
+ }
+
+ }
+ }
+ };
+ }
+ });
+ digester.addCallMethod("*/import", "doImport", 2);
+ digester.addCallParam("*/import", 0, "index");
+ digester.addCallParam("*/import", 1, "uri");
+// digester.addObjectCreate("index/resource", MagicResource.class);
+// snp = new SetNestedPropertiesRule();
+// snp.setAllowUnknownChildElements(true);
+// digester.addRule("index/resource/info", snp);
+// digester.addObjectCreate("index/resource/dependencies/include",
Dependency.class);
+// digester.addSetProperties("index/resource/dependencies/include");
+// digester.addSetNext("index/resource/dependencies/include",
"addDependency");
+// digester.addSetNext("index/resource", "addMagicResource");
+// digester.addObjectCreate("module/resources/resource",
MagicResource.class);
+// snp = new SetNestedPropertiesRule();
+// snp.setAllowUnknownChildElements(true);
+// digester.addRule("module/resources/resource/info", snp);
+//
digester.addObjectCreate("module/resources/resource/dependencies/include",
Dependency.class);
+//
digester.addSetProperties("module/resources/resource/dependencies/include");
+//
digester.addSetNext("module/resources/resource/dependencies/include",
"addDependency");
+// digester.addSetNext("module/resources/resource",
"addMagicResource");
+ addMessage(Message.MSG_INFO, "Parsing file " + file);
+ progress.setText2("Parsing file "+file);
+ digester.clear();
+ digester.push(this);
+ digester.parse(file);
+ }
+
+ /**
+ * Flatten the dependencies of the given Magic project.
+ *
+ * @param o The Magic project
+ *
+ * @throws UnresolvedDependencyException
+ */
+ private void flattenDependencies(MagicProject o) throws
UnresolvedDependencyException {
+ Set deps = new HashSet();
+ flattenDependencies(o, o, deps);
+ Iterator iter = deps.iterator();
+ while ( iter.hasNext() ) {
+ Dependency dep = (Dependency)iter.next();
+ o.addDependency(dep);
+ }
+ }
+
+ /**
+ * Flatten the dependencies of a Magic project. This will recursively
descend into the dependencies of the
+ * dependencies of the dependencies ... and add all of them to the root
Magic project.
+ *
+ * @param root The root Magic project the dependencies of which are
being flattened.
+ * @param o The current dependent object (Magic project of resource).
+ * @param deps A set of #{link Dependency} objects seen up to now. Used
for avoiding endless loops if there are circular dependencies.
+ * @throws UnresolvedDependencyException
+ */
+ private void flattenDependencies(MagicProject root, DependentObject o,
Set deps) throws UnresolvedDependencyException {
+ Iterator iter = o.getDependencies().iterator();
+ while ( iter.hasNext() ) {
+ Dependency dep = (Dependency)iter.next();
+ //DependentObject d = resolve(dep.getKey());
+ if ( !root.getName().equals(dep.getKey()) && !deps.contains(dep)
) {
+ deps.add(dep);
+ //root.addDependency(dep);
+ DependentObject resolved = resolve(dep.getKey());
+ // FIXME: DOESN'T LOOK RIGHT
+ if ( resolved != null ) flattenDependencies(root, resolved ,
deps);
+ }
+ }
+ }
+
+ /**
+ * Apply all dependencies collected by {@link
#collectDependencies(ProgressIndicator)} to their respective IDEA
+ * modules.
+ *
+ * @param progress A progress indicator.
+ *
+ * @throws UnresolvedDependencyException
+ * @throws ModuleCircularDependencyException
+ */
+ public void applyDependencies(final ProgressIndicator progress) throws
UnresolvedDependencyException, ModuleCircularDependencyException {
+ try {
+ boolean success = false;
+
+ // IDEA module cache. Maps Magic projects to IDEA modules.
+ final Map modules = collectModules();
+
+ final Application app = ApplicationManager.getApplication();
+ // a cache of root models; also used to commit/dispose the
changes
+ final Set rootModels = new LinkedHashSet();
+ // a cache of libraries (names mapped to IDEA Library objects);
also used to commit/dispose the changes
+ final Map libs = new LinkedHashMap();
+ model = moduleManager.getModifiableModel();
+ libraryModel =
LibraryTableUtil.getLibraryTable(project).getModifiableModel();
+
+ double currentProgress = 0;
+ double progressStep = 1.0/modules.size();
+ progress.setFraction(0);
+ progress.setText("Setting up modules...");
+ try {
+ Iterator iter = modules.entrySet().iterator();
+ while ( iter.hasNext() ) {
+ Map.Entry entry = (Map.Entry)iter.next();
+ final MagicProject magicProject =
(MagicProject)entry.getKey();
+ final Module module = (Module)entry.getValue();
+ progress.setText2("Setting up module " +
module.getName());
+ updateProgress();
+ app.invokeAndWait(new Runnable() {
+ public void run() {
+ app.runWriteAction(new Runnable() {
+ public void run() {
+ try {
+ setupModule(modules, rootModels,
libs, magicProject, module);
+ }
+ catch ( Throwable exc ) {
+ exception = exc;
+ }
+ }
+ });
+ }
+ }, app.getDefaultModalityState());
+ if ( exception != null ) {
+ if ( exception instanceof
UnresolvedDependencyException ) {
+ throw (UnresolvedDependencyException)exception;
+ }
+ else if ( exception instanceof RuntimeException ) {
+ throw (RuntimeException)exception;
+ }
+ else if ( exception instanceof Error ) {
+ throw (Error)exception;
+ }
+ else {
+ throw new RuntimeException("Unknown exception
caught", exception);
+ }
+ }
+ currentProgress += progressStep;
+ final double finalProgress = currentProgress;
+ progress.setFraction(finalProgress);
+ Thread.yield();
+ }
+ success = true;
+ }
+ finally {
+ progress.setText2("Committing changes...");
+ progress.startNonCancelableSection();
+ updateProgress();
+ final boolean finalSuccess = success;
+ app.invokeAndWait(new Runnable() {
+ public void run() {
+ app.runWriteAction(new Runnable() {
+ public void run() {
+ try {
+ cleanupBuild(finalSuccess, rootModels,
libs.values());
+ }
+ catch ( Throwable exc ) {
+ exception = exc;
+ }
+ }
+ });
+ }
+ }, app.getDefaultModalityState());
+ if ( exception != null ) {
+ if ( exception instanceof
ModuleCircularDependencyException ) {
+ throw (ModuleCircularDependencyException)exception;
+ }
+ else if ( exception instanceof RuntimeException ) {
+ throw (RuntimeException)exception;
+ }
+ else if ( exception instanceof Error ) {
+ throw (Error)exception;
+ }
+ else {
+ throw new RuntimeException("Unknown exception
caught", exception);
+ }
+ }
+ }
+ }
+ catch ( UnresolvedDependencyException exc ) {
+ exception = exc;
+ throw exc;
+ }
+ catch ( RuntimeException exc ) {
+ exception = exc;
+ throw exc;
+ }
+ catch ( Error exc ) {
+ exception = exc;
+ throw exc;
+ }
+ }
+
+ /**
+ * Setup a specific IDEA module. This method sets the module and library
dependencies creating the libraries, if
+ * needed (checking the library roots and modifying the libraries as
neccessary). It also sets the source and
+ * output paths of the module.
+ *
+ * @param modules The module cache.
+ * @param rootModels To root model cache.
+ * @param libs The library cache.
+ * @param magicProject The current Magic project.
+ * @param module The IDEA module.
+ *
+ * @throws UnresolvedDependencyException
+ */
+ private void setupModule(Map modules, Set rootModels, Map libs,
MagicProject magicProject, Module module) throws
UnresolvedDependencyException {
+ addMessage(Message.MSG_INFO, "Setting up module " +
module.getName());
+ ModuleRootManager rootManager =
ModuleRootManager.getInstance(module);
+ ModifiableRootModel rootModel = rootManager.getModifiableModel();
+ rootModels.add(rootModel);
+
+ ContentEntry[] contentEntries = rootModel.getContentEntries();
+ File moduleRootFile = new File(magicProject.getIndexPath(),
magicProject.getBasedir());
+ VirtualFile contentFile =
LocalFileSystem.getInstance().findFileByIoFile(moduleRootFile);
+ ContentEntry mainContent = null;
+ for ( int i = 0; i < contentEntries.length; i++ ) {
+ if ( contentEntries[i].getFile().equals(contentFile) ) {
+ mainContent = contentEntries[i];
+ }
+ else if ( config.getStrictSyncing() ) {
+ addMessage(Message.MSG_INFO, "Removing content entry " +
contentEntries[i].getFile());
+ rootModel.removeContentEntry(contentEntries[i]);
+ }
+ }
+ if ( mainContent == null ) {
+ addMessage(Message.MSG_INFO, "Adding content entry " +
contentFile);
+ rootModel.addContentEntry(contentFile);
+ }
+ File sourcePath = new File(moduleRootFile, "src");
+ VirtualFile mainFile =
LocalFileSystem.getInstance().findFileByIoFile(new File(sourcePath, "main"));
+ VirtualFile testFile =
LocalFileSystem.getInstance().findFileByIoFile(new File(sourcePath, "test"));
+ SourceFolder[] sourceFolders = mainContent.getSourceFolders();
+ boolean foundMain = false;
+ boolean foundTest = false;
+ for ( int i = 0; i < sourceFolders.length; i++ ) {
+ boolean remove = false;
+ if ( ObjectUtils.equals(sourceFolders[i].getFile(), mainFile) ) {
+ if ( sourceFolders[i].isTestSource() ) {
+ remove = true;
+ }
+ else {
+ foundMain = true;
+ }
+ }
+ else if ( ObjectUtils.equals(sourceFolders[i].getFile(),
testFile) ) {
+ if ( !sourceFolders[i].isTestSource() ) {
+ remove = true;
+ }
+ else {
+ foundTest = true;
+ }
+ }
+ else if ( config.getStrictSyncing() ) {
+ remove = true;
+ }
+ if ( remove ) {
+ if ( sourceFolders[i].isTestSource() ) {
+ addMessage(Message.MSG_INFO, "Removing test source
folder " + sourceFolders[i].getFile());
+ }
+ else {
+ addMessage(Message.MSG_INFO, "Removing source folder " +
sourceFolders[i].getFile());
+ }
+ mainContent.removeSourceFolder(sourceFolders[i]);
+ }
+ }
+ if ( !foundMain && mainFile != null ) {
+ addMessage(Message.MSG_INFO, "Adding source folder " + mainFile);
+ mainContent.addSourceFolder(mainFile, false);
+ }
+ if ( !foundTest && testFile != null ) {
+ mainContent.addSourceFolder(testFile, true);
+ }
+ rootModel.setCompilerOutputPath("file://" +
magicProject.getBasedir().replace(File.separatorChar, '/')+"/target/classes");
+ rootModel.setCompilerOutputPathForTests("file://" +
magicProject.getBasedir().replace(File.separatorChar,
'/')+"/target/test-classes");
+
+ Set currentOrderEntries = new HashSet();
+ OrderEntry[] orderEntries = rootModel.getOrderEntries();
+ for ( int i = 0; i < orderEntries.length; i++ ) {
+ if ( orderEntries[i] instanceof ModuleOrderEntry ) {
+
currentOrderEntries.add(((ModuleOrderEntry)orderEntries[i]).getModule());
+ }
+ else if ( orderEntries[i] instanceof LibraryOrderEntry ) {
+
currentOrderEntries.add(((LibraryOrderEntry)orderEntries[i]).getLibrary());
+ }
+ }
+ Iterator deps = magicProject.getDependencies().iterator();
+ while ( deps.hasNext() ) {
+ Dependency d = (Dependency)deps.next();
+ DependentObject resolved = resolve(d.getKey());
+ // FIXME: doesn't look right
+ if ( resolved == null ) continue;
+ if ( resolved instanceof MagicProject ) {
+ MagicProject projectDependency = (MagicProject)resolved;
+ Module other = (Module)modules.get(projectDependency);
+ if ( other == null ) {
+ addMessage(Message.MSG_WARNING, "No module found for
project " + projectDependency);
+ }
+ else {
+ if ( !currentOrderEntries.contains(other) ) {
+ addMessage(Message.MSG_INFO, "Adding module " +
projectDependency.getModuleName());
+ rootModel.addModuleOrderEntry(other);
+ }
+ }
+ }
+ else if ( resolved instanceof MagicResource ) {
+ MagicResource resource = (MagicResource)resolved;
+ addMessage(Message.MSG_INFO, "Adding resource " + resource);
+ String groupPath = resource.getGroup().replace('/',
File.separatorChar);
+ File path = new File(config.getCacheDir(), groupPath);
+ path = new File(path, resource.getType() + "s");
+ path = new File(path, resource.getName() + "-" +
resource.getVersion() + "." + resource.getType());
+ String libName = resource.getLibraryName();
+ LibraryEntry lib = (LibraryEntry)libs.get(libName);
+ boolean update = false;
+ if ( lib == null ) {
+ Library library = libraryModel.getLibraryByName(libName);
+ if ( library == null ) {
+ addMessage(Message.MSG_INFO, "Creating library " +
libName);
+ library = libraryModel.createLibrary(libName);
+ }
+ lib = new LibraryEntry(library);
+ libs.put(libName, lib);
+ update = true;
+ }
+ if ( update ) {
+ addMessage(Message.MSG_INFO, "Updating library " +
libName);
+ String url = "jar://" + path + "!/";
+ String[] libRoots =
lib.model.getUrls(OrderRootType.CLASSES);
+ boolean foundRoot = false;
+ for ( int i = 0; i < libRoots.length; i++ ) {
+ if ( libRoots[i].equals(url) ) {
+ foundRoot = true;
+ }
+ else if ( config.getStrictSyncing() ) {
+ addMessage(Message.MSG_INFO, "Removing library
root " + libRoots[i]);
+ lib.model.removeRoot(libRoots[i],
OrderRootType.CLASSES);
+ }
+ }
+ if ( !foundRoot ) {
+ addMessage(Message.MSG_INFO, "Adding root " + url +
" to library " + libName);
+ lib.model.addRoot(url, OrderRootType.CLASSES);
+ }
+ }
+ if ( !currentOrderEntries.contains(lib.lib) ) {
+ rootModel.addLibraryEntry(lib.lib);
+ }
+ }
+ else {
+ addMessage(Message.MSG_ERROR, "Invalid DependentObject
instance: " + resolved);
+ throw new IllegalStateException("Invalid DependentObject
instance: " + resolved);
+ }
+ }
+
+ if ( config.getJUnitLibrary() != null ) {
+ Library junit =
LibraryTableUtil.getLibraryTable().getLibraryByName(config.getJUnitLibrary());
+ if ( junit != null ) {
+ if ( !currentOrderEntries.contains(junit) ) {
+ rootModel.addLibraryEntry(junit);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets up the module cache by mapping Magic projects to IDEA modules
using the base directory of the Magic project.
+ *
+ * @return A map that maps Magic projects to IDEA modules.
+ */
+ private Map collectModules() {
+ Map modules = new HashMap();
+ ProjectRootManager projectRootManager =
ProjectRootManager.getInstance(project);
+ Iterator iter = magicProjects.values().iterator();
+ while ( iter.hasNext() ) {
+ MagicProject magicProject = (MagicProject)iter.next();
+ addMessage(Message.MSG_INFO, "Checking project " + magicProject);
+ Module module = null;
+ File moduleFile = (File)moduleFiles.get(new
File(magicProject.getIndexPath(), magicProject.getBasedir()).toString());
+ if ( moduleFile == null ) {
+ addMessage(Message.MSG_WARNING, "No IDEA module found in
directory " + magicProject.getIndexPath());
+ continue;
+ }
+ else {
+ module =
projectRootManager.getFileIndex().getModuleForFile(LocalFileSystem.getInstance().findFileByIoFile(moduleFile));
+ }
+ if ( module == null ) {
+ addMessage(Message.MSG_WARNING, "Module " + moduleFile + "
is not in the project");
+ }
+ else {
+ addMessage(Message.MSG_INFO, "Project " + magicProject +
"associated with module " + module.getName());
+ modules.put(magicProject, module);
+ }
+ }
+ return modules;
+ }
+
+ /**
+ * Resolve a dependency.
+ *
+ * @param key The key of the dependency
+ *
+ * @return The resolved Magic project or resource or <code>null</code>,
if the dependency could not be resolved.
+ *
+ * @throws UnresolvedDependencyException Currently not thrown.
+ */
+ private DependentObject resolve(String key) throws
UnresolvedDependencyException {
+ DependentObject o = (DependentObject)resolvedObjects.get(key);
+ if ( o == null ) {
+ o = (MagicProject)magicProjects.get(key);
+ if ( o == null ) {
+ o = (MagicResource)magicResources.get(key);
+ }
+ }
+ if ( o == null ) {
+ // FIXME: DOESN'T LOOK RIGHT
+ addMessage(Message.MSG_WARNING, "Cannot resolve dependency with
key " + key);
+ return null;
+ //throw new UnresolvedDependencyException("Cannot resolve
dependency with key " + key);
+ }
+ else {
+ return o;
+ }
+ }
+
+ /**
+ * Cleanup the project rebuild, i.e. commit or dispose all root/library
models.
+ *
+ * @param success If <code>true</code>, commit, else dispose.
+ * @param rootModels The root models.
+ * @param libs The library models.
+ *
+ * @throws ModuleCircularDependencyException If a circular module
dependency has been detected.
+ */
+ private void cleanupBuild(boolean success, Collection rootModels,
Collection libs) throws ModuleCircularDependencyException {
+ try {
+ Iterator iter = rootModels.iterator();
+ while ( iter.hasNext() ) {
+ ModifiableRootModel m = (ModifiableRootModel)iter.next();
+ if ( success ) {
+ addMessage(Message.MSG_INFO, "Committing root model " +
m);
+ m.commit();
+ }
+ else {
+ addMessage(Message.MSG_INFO, "Disposing root model " +
m);
+ m.dispose();
+ }
+ }
+ if ( model != null ) {
+ if ( success ) {
+ addMessage(Message.MSG_INFO, "Committing module model");
+ model.commit();
+ }
+ else {
+ addMessage(Message.MSG_INFO, "Disposing module model");
+ model.dispose();
+ }
+ }
+ if ( success && libraryModel != null ) {
+ addMessage(Message.MSG_INFO, "Committing library table
model");
+ libraryModel.commit();
+ iter = libs.iterator();
+ while ( iter.hasNext() ) {
+ LibraryEntry e = (LibraryEntry)iter.next();
+ addMessage(Message.MSG_INFO, "Committing library model
for " + e.lib.getName());
+ e.model.commit();
+ }
+ }
+ }
+ finally {
+ model = null;
+ libraryModel = null;
+ }
+ }
+
+ /**
+ * Workaround; finde something nicer here; wait a bit hoping the AWT
event queue find some time to update the
+ * progress indicator.
+ */
+ private void updateProgress() {
+ try {
+ Thread.sleep(100);
+ }
+ catch ( InterruptedException e ) {
+ // ignore
+ }
+
+ }
+
+// private void addMessage(String msg) {
+// addMessage(Message.MSG_INFO, msg);
+// }
+
+ /**
+ * Add a message to the list of messages. Also logs the messages.
+ *
+ * @param type The message type ({@link Message#MSG_INFO}, {@link
Message#MSG_WARNING} or {@link Message#MSG_ERROR}).
+ * @param msg
+ */
+ private void addMessage(int type, String msg) {
+ switch ( type ) {
+ case Message.MSG_INFO:
+ log.info(msg);
+ break;
+ case Message.MSG_WARNING:
+ log.info("WARNING: "+msg);
+ break;
+ case Message.MSG_ERROR:
+ log.error(msg);
+ break;
+ }
+ messages.add(new Message(type, msg));
+ }
+
+
+
+
+ /*
+ * hooks for digester
+ */
+
+ /**
+ * Called by the digester to add a new Magic project.
+ * <p>
+ * <strong>FIXME: put this into an inner class</strong>
+ *
+ * @param project The new Magic project.
+ */
+ public void addMagicProject(MagicProject project) {
+ magicProjects.put(project.getName(), project);
+ }
+
+ /**
+ * Called by the digester to add a new Magic resource.
+ * <p>
+ * <strong>FIXME: put this into an inner class</strong>
+ *
+ * @param resource The new Magic resource.
+ */
+ public void addMagicResource(MagicResource resource) {
+ magicResources.put(resource.getName(), resource);
+ }
+
+
+
+ /*
+ * getters and setters
+ */
+
+ /**
+ * Get the exception that has occurred, if any.
+ *
+ * @return The exception or <code>null</code>, if none occurred.
+ */
+ public Throwable getException() {
+ return exception;
+ }
+
+
+
+ /*
+ * inner classes
+ */
+
+ private final static class LibraryEntry {
+ private final Library lib;
+ private final Library.ModifiableModel model;
+ private LibraryEntry(Library lib) {
+ this.lib = lib;
+ this.model = lib.getModifiableModel();
+ }
+ }
+
+ final static class UnresolvedDependencyException extends Exception {
+ public UnresolvedDependencyException() {
+ super();
+ }
+ public UnresolvedDependencyException(String message) {
+ super(message);
+ }
+ public UnresolvedDependencyException(Throwable cause) {
+ super(cause);
+ }
+ public UnresolvedDependencyException(String message, Throwable
cause) {
+ super(message, cause);
+ }
+ }
+
+
+
+ /*
+ * obsolete stuff
+ */
+
+// void old_collect() throws SAXException, IOException {
+// SetNestedPropertiesRule snp;
+// Digester digester = new Digester();
+// digester.addFactoryCreate("index/project", new
AbstractObjectCreationFactory() {
+// public Object createObject(Attributes attributes) throws
Exception {
+// MagicProject prj = new MagicProject();
+// prj.setIndexPath(currentIndexPath);
+// return prj;
+// }
+// });
+// digester.addSetProperties("index/project");
+// snp = new SetNestedPropertiesRule();
+// snp.setAllowUnknownChildElements(true);
+// digester.addRule("index/project/info", snp);
+// digester.addSetNext("index/project", "addMagicProject");
+// digester.addObjectCreate("index/project/dependencies/include",
Dependency.class);
+// digester.addSetProperties("index/project/dependencies/include");
+// digester.addSetNext("index/project/dependencies/include",
"addDependency");
+// digester.addObjectCreate("index/resource", MagicResource.class);
+// snp = new SetNestedPropertiesRule();
+// snp.setAllowUnknownChildElements(true);
+// digester.addRule("index/resource/info", snp);
+// digester.addObjectCreate("index/resource/dependencies/include",
Dependency.class);
+// digester.addSetProperties("index/resource/dependencies/include");
+// digester.addSetNext("index/resource/dependencies/include",
"addDependency");
+// digester.addSetNext("index/resource", "addMagicResource");
+//
+// Iterator iter = indexFiles.iterator();
+// while (iter.hasNext()) {
+// progress.checkCanceled();
+// File f = (File) iter.next();
+// currentIndexPath = f.getParent().toString();
+// log.info("Parsing file " + f);
+// progress.setText2("Parsing file "+f);
+// digester.clear();
+// digester.push(this);
+// digester.parse(f);
+// }
+//
+// if ( DUMP ) {
+// iter = magicProjects.values().iterator();
+// while (iter.hasNext()) {
+// MagicProject m = (MagicProject)iter.next();
+// log.info("Project: " + m.getGroup() + ":" + m.getName() +
" (" + m.getBasedir() + ")");
+// Iterator iter2 = m.getDependencies().iterator();
+// while (iter2.hasNext()) {
+// Dependency d = (Dependency)iter2.next();
+// log.info(" Dependency: "+d.getKey()+"; build:
"+d.isBuild()+"; test: "+d.isTest()+"; runtime: "+d.isRuntime());
+// }
+// }
+// iter = magicResources.values().iterator();
+// while (iter.hasNext()) {
+// MagicResource r = (MagicResource)iter.next();
+// log.info("Resource: " + r.getGroup() + ":" + r.getName() +
"#" + r.getVersion());
+// Iterator iter2 = r.getDependencies().iterator();
+// while (iter2.hasNext()) {
+// Dependency d = (Dependency)iter2.next();
+// log.info(" Dependency: "+d.getKey()+"; build:
"+d.isBuild()+"; test: "+d.isTest()+"; runtime: "+d.isRuntime());
+// }
+// }
+// }
+// }
+//
+// public void old_build() {
+// progress.setText("Checking dependencies...");
+// Comparator topSortComparator;
+// try {
+// topSortComparator = circularDependencyCheck();
+// }
+// catch ( UnresolvedDependencyException exc ) {
+// log.error(exc);
+// return;
+// }
+// catch ( TopSort.CyclicGraphException exc ) {
+// log.error(exc);
+// return;
+// }
+// List sortedProjects = new ArrayList(magicProjects.values());
+// Collections.sort(sortedProjects, topSortComparator);
+//
+// boolean success = false;
+// List rootModels = new LinkedList();
+// List libModels = new LinkedList();
+// model = moduleManager.getModifiableModel();
+// libraryModel =
LibraryTableUtil.getLibraryTable(project).getModifiableModel();
+// try {
+// double progressValue = 0.0;
+//
+// progress.setText("Building modules...");
+// Iterator iter = sortedProjects.iterator();
+// final double step = 1.0 / magicProjects.size();
+// progress.setIndeterminate(false);
+// while ( iter.hasNext() ) {
+// progress.checkCanceled();
+// MagicProject magicProject = (MagicProject)iter.next();
+// String moduleName = magicProject.getModuleName();
+// log.info("Setting up module " + moduleName);
+// progress.setText2("Setting up module " + moduleName);
+// progressValue += step;
+// progress.setFraction(progressValue);
+// Module module = moduleManager.findModuleByName(moduleName);
+// if ( module == null ) {
+// String path = new File(magicProject.getIndexPath(),
magicProject.getBasedir()).toString();
+// log.info("Creating module at " + path);
+// module = moduleManager.newModule(path,
ModuleType.JAVA);
+// }
+// ModuleRootManager rootManager =
ModuleRootManager.getInstance(module);
+// ModifiableRootModel rootModel =
rootManager.getModifiableModel();
+// rootModels.add(rootModel);
+//
rootModel.addContentEntry(LocalFileSystem.getInstance().findFileByIoFile(
+// new File(magicProject.getIndexPath(),
magicProject.getBasedir())
+// ));
+//
+// if ( false && !ObjectUtils.equals(module.getName(),
moduleName) ) {
+// log.info("Renaming module named " + module.getName() +
" to " + moduleName);
+// model.renameModule(module, moduleName);
+// }
+//
+// Iterator deps = magicProject.getDependencies().iterator();
+// while ( deps.hasNext() ) {
+// progress.checkCanceled();
+// Dependency d = (Dependency)deps.next();
+// DependentObject resolved =
(DependentObject)resolvedObjects.get(d.getKey());
+// if ( resolved instanceof MagicProject ) {
+// MagicProject projectDependency =
(MagicProject)resolved;
+// log.info("Adding module " +
projectDependency.getModuleName());
+// Module other =
moduleManager.findModuleByName(projectDependency.getModuleName());
+// if ( other == null ) {
+// other =
model.getModuleToBeRenamed(projectDependency.getModuleName());
+// }
+// if ( other == null ) {
+// throw new IllegalStateException("Module " +
projectDependency.getModuleName() + " not found");
+// }
+// rootModel.addModuleOrderEntry(other);
+// }
+// else if ( resolved instanceof MagicResource ) {
+// MagicResource resource = (MagicResource)resolved;
+// log.info("Adding resource " + resource);
+// String groupPath =
resource.getGroup().replace('/', File.separatorChar);
+// File path = new File(config.getCacheDir(),
groupPath);
+// path = new File(path, resource.getType() + "s");
+// path = new File(path, resource.getName() + "-" +
resource.getVersion() + "." + resource.getType());
+// String libName = resource.getLibraryName();
+// Library lib =
libraryModel.getLibraryByName(libName);
+// if ( lib == null ) {
+// log.info("Creating library " + libName);
+// lib = libraryModel.createLibrary(libName);
+// }
+// Library.ModifiableModel libModel =
lib.getModifiableModel();
+// libModels.add(libModel);
+// String url = "jar://" + path + "!/";
+// String[] libRoots =
libModel.getUrls(OrderRootType.CLASSES);
+// boolean foundRoot = false;
+// for ( int i = 0; i < libRoots.length; i++ ) {
+// if ( libRoots[i].equals(url) ) {
+// foundRoot = true;
+// break;
+// }
+// }
+// if ( !foundRoot ) {
+// log.info("Adding root " + url + " to library "
+ libName);
+// libModel.addRoot(url, OrderRootType.CLASSES);
+// }
+// rootModel.addLibraryEntry(lib);
+// }
+// else {
+// log.error("Invalid DependentObject instance: " +
resolved);
+// throw new IllegalStateException("Invalid
DependentObject instance: " + resolved);
+// }
+// }
+// }
+// success = true;
+// }
+// catch ( ModuleWithNameAlreadyExists exc ) {
+// log.error(exc);
+// }
+// finally {
+// cleanupBuild(success, rootModels, libModels);
+// }
+// }
+//
+//
+// private Comparator circularDependencyCheck() throws
UnresolvedDependencyException, TopSort.CyclicGraphException {
+// TopSort ts = new TopSort();
+// Set seen = new HashSet(magicProjects.size()+magicResources.size());
+// circularDependencyCheck(ts, seen, magicProjects.values());
+// circularDependencyCheck(ts, seen, magicResources.values());
+// ts.topSort();
+// return ts.getComparator();
+// }
+//
+// private void circularDependencyCheck(TopSort ts, Set seen, Collection
check) throws UnresolvedDependencyException {
+// Iterator iter = check.iterator();
+// while ( iter.hasNext() ) {
+// DependentObject o = (DependentObject)iter.next();
+// seen.add(o);
+// circularDependencyCheck(ts, seen, o);
+// }
+// }
+//
+// private void circularDependencyCheck(TopSort ts, Set seen,
DependentObject o) throws UnresolvedDependencyException {
+// progress.checkCanceled();
+// Iterator iter = o.getDependencies().iterator();
+// while ( iter.hasNext() ) {
+// Dependency d = (Dependency)iter.next();
+// DependentObject resolved =
(DependentObject)resolvedObjects.get(d.getKey());
+// boolean updateResolved = false;
+// if ( resolved == null ) {
+// resolved = (DependentObject)magicProjects.get(d.getKey());
+// updateResolved = true;
+// }
+// if ( resolved == null ) {
+// resolved = (DependentObject)magicResources.get(d.getKey());
+// }
+// if ( resolved == null ) {
+// throw new UnresolvedDependencyException("Could not resolve
dependency with key " + d.getKey());
+// }
+// if ( updateResolved ) {
+// resolvedObjects.put(d.getKey(), resolved);
+// }
+// boolean descend = !seen.contains(d);
+// if ( !descend ) {
+// seen.add(resolved);
+// }
+// ts.addArc(o, resolved);
+// if ( descend ) {
+// circularDependencyCheck(ts, seen, resolved);
+// }
+// }
+// }
+
+}

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/SettingsForm.form
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/SettingsForm.form
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/"; version="1"
bind-to-class="net.dpml.ide.idea.plugin.magic.SettingsForm">
+ <grid id="a38b3" binding="rootPanel" row-count="2" column-count="3"
same-size-horizontally="false" same-size-vertically="false" hgap="-1"
vgap="-1">
+ <margin top="5" left="5" bottom="5" right="5"/>
+ <constraints>
+ <xy x="38" y="12" width="465" height="321"/>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3"
hsize-policy="3" anchor="0" fill="3"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="cf80a" class="javax.swing.JCheckBox" binding="sync">
+ <constraints>
+ <xy x="5" y="5" width="157" height="23"/>
+ <grid row="0" column="0" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="0" anchor="1" fill="0"/>
+ </constraints>
+ <properties>
+ <text value="Synchronize with Magic"/>
+ </properties>
+ </component>
+ <grid id="c8c2f" binding="optionsPanel" row-count="4" column-count="2"
same-size-horizontally="false" same-size-vertically="false" hgap="-1"
vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="5" y="35" width="455" height="281"/>
+ <grid row="1" column="0" row-span="1" col-span="3"
vsize-policy="7" hsize-policy="7" anchor="0" fill="3"/>
+ </constraints>
+ <properties>
+ <visible value="true"/>
+ </properties>
+ <border type="etched"/>
+ <children>
+ <component id="3a6f2" class="javax.swing.JCheckBox"
binding="strict">
+ <constraints>
+ <xy x="2" y="2" width="192" height="23"/>
+ <grid row="0" column="0" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="0" anchor="8" fill="0"/>
+ </constraints>
+ <properties>
+ <text value="Strict Module Synchronization"/>
+ </properties>
+ </component>
+ <component id="453be" class="javax.swing.JCheckBox"
binding="recursiveDependencies">
+ <constraints>
+ <xy x="2" y="30" width="212" height="23"/>
+ <grid row="1" column="0" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="3" anchor="8" fill="0"/>
+ </constraints>
+ <properties>
+ <label value="Apply Dependencies Recursively"/>
+ <text value="Apply Dependencies Recursively"/>
+ </properties>
+ </component>
+ <grid id="be1e" binding="optionsPanel2" row-count="2"
column-count="3" same-size-horizontally="false" same-size-vertically="false"
hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="2" y="58" width="451" height="52"/>
+ <grid row="2" column="0" row-span="1" col-span="2"
vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="79000" class="javax.swing.JLabel"
binding="junitLabel">
+ <constraints>
+ <xy x="30" y="4" width="70" height="15"/>
+ <grid row="0" column="0" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="0" anchor="4" fill="0"/>
+ </constraints>
+ <properties>
+ <text value="JUnit Library"/>
+ </properties>
+ </component>
+ <component id="f163b" class="javax.swing.JLabel"
binding="cacheLabel">
+ <constraints>
+ <xy x="0" y="33" width="100" height="15"/>
+ <grid row="1" column="0" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="0" anchor="4" fill="0"/>
+ </constraints>
+ <properties>
+ <text value="DPML Cache Path"/>
+ </properties>
+ </component>
+ <component id="d6478" class="javax.swing.JTextField"
binding="cache">
+ <constraints>
+ <xy x="110" y="29" width="265" height="22"/>
+ <grid row="1" column="1" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="75f6e" class="javax.swing.JComboBox"
binding="junit">
+ <constraints>
+ <xy x="110" y="0" width="265" height="24"/>
+ <grid row="0" column="1" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="6" anchor="8" fill="1"/>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="e2420" class="javax.swing.JCheckBox"
binding="defaultCache">
+ <constraints>
+ <xy x="385" y="29" width="66" height="23"/>
+ <grid row="1" column="2" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="0" anchor="8" fill="0"/>
+ </constraints>
+ <properties>
+ <label value="Default"/>
+ <text value="Default"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <vspacer id="72cc8">
+ <constraints>
+ <xy x="437" y="110" width="11" height="169"/>
+ <grid row="3" column="1" row-span="1" col-span="1"
vsize-policy="6" hsize-policy="1" anchor="0" fill="2"/>
+ </constraints>
+ </vspacer>
+ </children>
+ </grid>
+ <component id="5d3ad" class="javax.swing.JButton" binding="syncNow">
+ <constraints>
+ <xy x="329" y="5" width="131" height="25"/>
+ <grid row="0" column="2" row-span="1" col-span="1"
vsize-policy="0" hsize-policy="0" anchor="1" fill="1"/>
+ </constraints>
+ <properties>
+ <enabled value="false"/>
+ <text value="Synchronize Now"/>
+ </properties>
+ </component>
+ <hspacer id="23eac">
+ <constraints>
+ <xy x="172" y="12" width="157" height="11"/>
+ <grid row="0" column="1" row-span="1" col-span="1"
vsize-policy="1" hsize-policy="6" anchor="0" fill="1"/>
+ </constraints>
+ </hspacer>
+ </children>
+ </grid>
+</form>

Added:
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/SettingsForm.java
==============================================================================
--- (empty file)
+++
development/laboratory/ide/idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic/SettingsForm.java
Sun Feb 13 16:08:43 2005
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2005 Raffael Herzog
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.dpml.ide.idea.plugin.magic;
+
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Iterator;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTableUtil;
+
+/**
+ * GUI controller for the settings form.
+ *
+ */
+public class SettingsForm {
+
+ private final Project project;
+ private final Logger log;
+ private Configuration config;
+
+ private JPanel rootPanel;
+
+ private JCheckBox sync;
+ private JButton syncNow;
+
+ private JPanel optionsPanel;
+ private JCheckBox strict;
+ private JCheckBox recursiveDependencies;
+
+ private JPanel optionsPanel2;
+ private JLabel junitLabel;
+ private JComboBox junit;
+ private JLabel cacheLabel;
+ private JTextField cache;
+ private JCheckBox defaultCache;
+
+ private final Map libraries;
+
+ public SettingsForm(Project project, Logger log, Configuration config) {
+ this.project = project;
+ this.log = log;
+ optionsPanel.setVisible(false);
+ sync.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ syncNow.setEnabled(sync.isSelected());
+ optionsPanel.setVisible(sync.isSelected());
+ }
+ });
+ defaultCache.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ cacheLabel.setEnabled(!defaultCache.isSelected());
+ cache.setEnabled(!defaultCache.isSelected());
+ }
+ });
+ syncNow.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ apply();
+ ProjectBuilder.rebuildProject(SettingsForm.this.project,
SettingsForm.this.log, SettingsForm.this.config);
+ }
+ });
+
+ Library[] libs = LibraryTableUtil.getLibraryTable().getLibraries();
+ libraries = new TreeMap(String.CASE_INSENSITIVE_ORDER);
+ for ( int i = 0; i < libs.length; i++ ) {
+ libraries.put(libs[i].getName(), libs[i]);
+ }
+ Iterator iter = libraries.keySet().iterator();
+ while ( iter.hasNext() ) {
+ String lib = (String)iter.next();
+ junit.addItem(lib);
+ }
+ if ( config.getJUnitLibrary() != null ) {
+ junit.setSelectedItem(libraries.get(config.getJUnitLibrary()));
+ }
+
+ rootPanel.revalidate();
+ setConfig(config);
+ }
+
+ public JPanel getRootPanel() {
+ return rootPanel;
+ }
+
+ /**
+ * Set the current configuration object and update the states of the GUI
elements.
+ *
+ * @param config The new configuration.
+ */
+ public void setConfig(Configuration config) {
+ this.config = config;
+ sync.setSelected(config.getSyncWithMagic());
+ strict.setSelected(config.getStrictSyncing());
+ recursiveDependencies.setSelected(config.getRecursiveDependencies());
+ cache.setText(config.getCacheDir());
+ if ( config.getJUnitLibrary() != null ) {
+ junit.setSelectedItem(libraries.get(config.getJUnitLibrary()));
+ }
+ else {
+ junit.setSelectedItem(null);
+ }
+ defaultCache.setSelected(!config.hasCacheDir());
+ }
+
+ /**
+ * Apply the current states of the GUI elements to the current
configuration.
+ *
+ * @return The current configuration.
+ */
+ public Configuration apply() {
+ config.setSyncWithMagic(sync.isSelected());
+ config.setStrictSyncing(strict.isSelected());
+ config.setRecursiveDependencies(recursiveDependencies.isSelected());
+ config.setJUnitLibrary((String)junit.getSelectedItem());
+ if ( defaultCache.isSelected() ) {
+ config.setCacheDir(null);
+ }
+ else {
+ config.setCacheDir(cache.getText());
+ }
+ return config;
+ }
+
+
+ //
+ // WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
+ //
+ // THIS CODE IN THIS BLOCK IS AUTOMATICALLY GENERATED BY THE GUI
SOURCE
+ // PLUGIN. ANY CHNAGE TO THIS CODE WILL BE OVER WRITTEN
+ // THE NEXT TIME THIS CODE IS GENERATED.
+ //
+ // WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
+ //
+
+ {
+ _initGeneratedUICode();
+ }
+
+ //
+ // WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
WARNING!
+ //
+ // THIS CODE IN _initGeneratedUICode() IS AUTOMATICALLY GENERATED BY
THE GUI
+ // SOURCE PLUGIN. ANY CHNAGE TO THIS CODE WILL BE OVER WRITTEN
+ // THE NEXT TIME THIS CODE IS GENERATED.
+ //
+ // WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
WARNING!
+ //
+
+ private void _initGeneratedUICode() {
+
+ com.intellij.uiDesigner.core.Spacer tmpSpacer;
+
+
+
+ rootPanel = new javax.swing.JPanel();
+ rootPanel.setLayout(new
com.intellij.uiDesigner.core.GridLayoutManager(2, 3,
+ new Insets(5, 5, 5, 5), -1, -1));
+
+
+ sync = new javax.swing.JCheckBox();
+ sync.setText("Synchronize with Magic");
+ rootPanel.add(sync, new
com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, 1, 0, 0, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ optionsPanel = new javax.swing.JPanel();
+ optionsPanel.setVisible(true);
+ optionsPanel.setLayout(new
com.intellij.uiDesigner.core.GridLayoutManager(4, 2,
+ new Insets(0, 0, 0, 0), -1, -1));
+
optionsPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+ rootPanel.add(optionsPanel, new
com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 3, 0, 3, 7, 7,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ strict = new javax.swing.JCheckBox();
+ strict.setText("Strict Module Synchronization");
+ optionsPanel.add(strict, new
com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, 8, 0, 0, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ recursiveDependencies = new javax.swing.JCheckBox();
+ recursiveDependencies.setText("Apply Dependencies Recursively");
+ optionsPanel.add(recursiveDependencies, new
com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1, 8, 0, 3, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ optionsPanel2 = new javax.swing.JPanel();
+ optionsPanel2.setLayout(new
com.intellij.uiDesigner.core.GridLayoutManager(2, 3,
+ new Insets(0, 0, 0, 0), -1, -1));
+ optionsPanel.add(optionsPanel2, new
com.intellij.uiDesigner.core.GridConstraints(2, 0, 1, 2, 0, 3, 3, 3,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ junitLabel = new javax.swing.JLabel();
+ junitLabel.setText("JUnit Library");
+ optionsPanel2.add(junitLabel, new
com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, 4, 0, 0, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ cacheLabel = new javax.swing.JLabel();
+ cacheLabel.setText("DPML Cache Path");
+ optionsPanel2.add(cacheLabel, new
com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1, 4, 0, 0, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ cache = new javax.swing.JTextField();
+ optionsPanel2.add(cache, new
com.intellij.uiDesigner.core.GridConstraints(1, 1, 1, 1, 8, 1, 6, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(150, -1), new java.awt.Dimension(-1, -1)));
+
+
+ junit = new javax.swing.JComboBox();
+ optionsPanel2.add(junit, new
com.intellij.uiDesigner.core.GridConstraints(0, 1, 1, 1, 8, 1, 6, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ defaultCache = new javax.swing.JCheckBox();
+ defaultCache.setText("Default");
+ optionsPanel2.add(defaultCache, new
com.intellij.uiDesigner.core.GridConstraints(1, 2, 1, 1, 8, 0, 0, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+ tmpSpacer = new com.intellij.uiDesigner.core.Spacer();
+ optionsPanel.add(tmpSpacer, new
com.intellij.uiDesigner.core.GridConstraints(3, 1, 1, 1, 0, 2, 1, 6,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+
+ syncNow = new javax.swing.JButton();
+ syncNow.setText("Synchronize Now");
+ syncNow.setEnabled(false);
+ rootPanel.add(syncNow, new
com.intellij.uiDesigner.core.GridConstraints(0, 2, 1, 1, 1, 1, 0, 0,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+ tmpSpacer = new com.intellij.uiDesigner.core.Spacer();
+ rootPanel.add(tmpSpacer, new
com.intellij.uiDesigner.core.GridConstraints(0, 1, 1, 1, 0, 1, 6, 1,
+ new java.awt.Dimension(-1, -1), new
java.awt.Dimension(-1, -1), new java.awt.Dimension(-1, -1)));
+
+ }
+
+
+}



  • svn commit: r1772 - in development/laboratory/ide: . idea-plugin idea-plugin/etc idea-plugin/magic idea-plugin/magic/etc idea-plugin/magic/etc/main idea-plugin/magic/etc/main/net idea-plugin/magic/etc/main/net/dpml idea-plugin/magic/etc/main/net/dpml/ide idea-plugin/magic/etc/main/net/dpml/ide/idea idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin idea-plugin/magic/etc/main/net/dpml/ide/idea/plugin/magic idea-plugin/magic/src idea-plugin/magic/src/main idea-plugin/magic/src/main/net idea-plugin/magic/src/main/net/dpml idea-plugin/magic/src/main/net/dpml/ide idea-plugin/magic/src/main/net/dpml/ide/idea idea-plugin/magic/src/main/net/dpml/ide/idea/plugin idea-plugin/magic/src/main/net/dpml/ide/idea/plugin/magic, herzog, 02/13/2005

Archive powered by MHonArc 2.6.24.

Top of Page