Revision: 1090
http://stripes.svn.sourceforge.net/stripes/?rev=1090&view=rev
Author: bengunter
Date: 2009-03-03 03:58:40 +0000 (Tue, 03 Mar 2009)
Log Message:
-----------
Rolled back the following commit because we no longer think it is
appropriate for release 1.5.1. Look for this change in release 1.6.
========================================================================
r1051 | fdaoud | 2009-02-25 14:37:57 -0600 (Wed, 25 Feb 2009) | 1 line
Removed unused SiteStructureTool and hostedqa
Modified Paths:
--------------
branches/1.5.x/.classpath
branches/1.5.x/build.xml
branches/1.5.x/examples/build.xml
Added Paths:
-----------
branches/1.5.x/build/lib/hostedqa.jar
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html
Removed Paths:
-------------
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html
Modified: branches/1.5.x/.classpath
===================================================================
--- branches/1.5.x/.classpath 2009-03-03 02:20:59 UTC (rev 1089)
+++ branches/1.5.x/.classpath 2009-03-03 03:58:40 UTC (rev 1090)
@@ -7,6 +7,7 @@
<classpathentry kind="lib"
path="stripes/lib/deploy/commons-logging.jar"/>
<classpathentry kind="lib" path="stripes/lib/deploy/cos.jar"/>
<classpathentry kind="lib" path="stripes/lib/build/el-api.jar"/>
+ <classpathentry kind="lib" path="build/lib/hostedqa.jar"/>
<classpathentry kind="lib" path="stripes/lib/build/jsp-api.jar"/>
<classpathentry kind="lib" path="stripes/lib/test/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="stripes/lib/build/mail.jar"/>
Copied: branches/1.5.x/build/lib/hostedqa.jar (from rev 1050,
branches/1.5.x/build/lib/hostedqa.jar)
===================================================================
(Binary files differ)
Modified: branches/1.5.x/build.xml
===================================================================
--- branches/1.5.x/build.xml 2009-03-03 02:20:59 UTC (rev 1089)
+++ branches/1.5.x/build.xml 2009-03-03 03:58:40 UTC (rev 1090)
@@ -52,6 +52,22 @@
</target>
<!-- ===================================================================
-->
+ <!-- Path and target that is used to build Stripes in the hosted QA env.
-->
+ <!-- ===================================================================
-->
+ <path id="hostedqa.classpath">
+ <fileset dir="build/lib">
+ <include name="**/*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="hostedqa" depends="build">
+ <taskdef resource="hostedqatasks"
classpathref="hostedqa.classpath"/>
+ <upload file="examples/dist/stripes-examples.war" account="stripes"
email="${hostedqa.email}" password="${hostedqa.password}" resourceId="19"/>
+ <playsuite suiteId="17" clientConfigs="19" appConfigs="18,19"
account="stripes" email="${hostedqa.email}" password="${hostedqa.password}"/>
+ </target>
+
+
+ <!-- ===================================================================
-->
<!-- Runs the clean target of both Stripes and the Examples project.
-->
<!-- ===================================================================
-->
<target name="clean" description="Cleans all build products for all three
sub-projects.">
Modified: branches/1.5.x/examples/build.xml
===================================================================
--- branches/1.5.x/examples/build.xml 2009-03-03 02:20:59 UTC (rev 1089)
+++ branches/1.5.x/examples/build.xml 2009-03-03 03:58:40 UTC (rev 1090)
@@ -95,6 +95,21 @@
</javadoc>
</target>
+ <target name="apt" depends="compile"
+ description="Builds an XML file showing the structure of the
examples web application.">
+ <pathconvert property="cp" refid="build.class.path"/>
+ <path id="srcfiles">
+ <fileset dir="${src.dir}" includes="**/*.java"/>
+ </path>
+ <pathconvert property="srcfiles" refid="srcfiles" pathsep=" "/>
+ <exec executable="apt">
+ <arg line="-classpath ${cp} -nocompile"/>
+ <arg line="-factory
net.sourceforge.stripes.tools.SiteStructureTool"/>
+ <arg line="-Astripes.output.file=sitemap.xml"/>
+ <arg line="${srcfiles}"/>
+ </exec>
+ </target>
+
<!-- =================================================================== -->
<!-- Tasks to deploy the application in Tomcat. -->
<!-- =================================================================== -->
Deleted:
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java
===================================================================
---
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java
2009-02-25 20:33:11 UTC (rev 1050)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java
2009-03-03 03:58:40 UTC (rev 1090)
@@ -1,68 +0,0 @@
-/* Copyright 2005-2006 Tim Fennell
- *
- * 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.sourceforge.stripes.tools;
-
-import net.sourceforge.stripes.action.UrlBinding;
-
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Encapsulates meta-information about an ActionBean, namely it's UrlBinding
and set of events
- * to which it responds. This class is not used at runtime in Stripes, but is
used by the
- * {...@link SiteStructureTool} to collect and report on information about
ActionBeans.
- *
- * @author Tim Fennell
- * @since Stripes 1.1.2
- */
-public class ActionBeanInfo {
- private String className;
- private UrlBinding urlBinding;
- private Map<String,EventInfo> events = new TreeMap<String,EventInfo>();
- private EventInfo defaultEvent;
-
- /** The class name of the ActionBean that this object describes. */
- public String getClassName() { return className; }
-
- /** The class name of the ActionBean that this object describes. */
- public void setClassName(String className) { this.className = className; }
-
- /** The UrlBinding extracted from the ActionBean. */
- public UrlBinding getUrlBinding() { return urlBinding; }
-
- /** The UrlBinding extracted from the ActionBean. */
- public void setUrlBinding(UrlBinding urlBinding) { this.urlBinding =
urlBinding; }
-
- /**
- * Adds the supplied event to the events for this ActionBean. If the event
is the default
- * event it will be stored separately, and not as part of the Map of
events.
- */
- public void addEvent(EventInfo eventInfo) {
- if (eventInfo.isDefaultEvent()) {
- this.defaultEvent = eventInfo;
- }
- else {
- this.events.put(eventInfo.getName(), eventInfo);
- }
- }
-
- /** Gets a Map of event name to EventInfo, excluding the default event. */
- public Map<String, EventInfo> getEvents() { return events; }
-
- /** Gets the default event for this ActionBean, if there is one. */
- public EventInfo getDefaultEvent() {
- return this.defaultEvent;
- }
-}
Copied:
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java
(from rev 1050,
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java)
===================================================================
---
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java
(rev 0)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/ActionBeanInfo.java
2009-03-03 03:58:40 UTC (rev 1090)
@@ -0,0 +1,68 @@
+/* Copyright 2005-2006 Tim Fennell
+ *
+ * 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.sourceforge.stripes.tools;
+
+import net.sourceforge.stripes.action.UrlBinding;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Encapsulates meta-information about an ActionBean, namely it's UrlBinding
and set of events
+ * to which it responds. This class is not used at runtime in Stripes, but is
used by the
+ * {...@link SiteStructureTool} to collect and report on information about
ActionBeans.
+ *
+ * @author Tim Fennell
+ * @since Stripes 1.1.2
+ */
+public class ActionBeanInfo {
+ private String className;
+ private UrlBinding urlBinding;
+ private Map<String,EventInfo> events = new TreeMap<String,EventInfo>();
+ private EventInfo defaultEvent;
+
+ /** The class name of the ActionBean that this object describes. */
+ public String getClassName() { return className; }
+
+ /** The class name of the ActionBean that this object describes. */
+ public void setClassName(String className) { this.className = className; }
+
+ /** The UrlBinding extracted from the ActionBean. */
+ public UrlBinding getUrlBinding() { return urlBinding; }
+
+ /** The UrlBinding extracted from the ActionBean. */
+ public void setUrlBinding(UrlBinding urlBinding) { this.urlBinding =
urlBinding; }
+
+ /**
+ * Adds the supplied event to the events for this ActionBean. If the event
is the default
+ * event it will be stored separately, and not as part of the Map of
events.
+ */
+ public void addEvent(EventInfo eventInfo) {
+ if (eventInfo.isDefaultEvent()) {
+ this.defaultEvent = eventInfo;
+ }
+ else {
+ this.events.put(eventInfo.getName(), eventInfo);
+ }
+ }
+
+ /** Gets a Map of event name to EventInfo, excluding the default event. */
+ public Map<String, EventInfo> getEvents() { return events; }
+
+ /** Gets the default event for this ActionBean, if there is one. */
+ public EventInfo getDefaultEvent() {
+ return this.defaultEvent;
+ }
+}
Deleted: branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java
2009-02-25 20:33:11 UTC (rev 1050)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java
2009-03-03 03:58:40 UTC (rev 1090)
@@ -1,60 +0,0 @@
-/* Copyright 2005-2006 Tim Fennell
- *
- * 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.sourceforge.stripes.tools;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Encapsulates meta-information about a single event within an ActionBean.
This class is not
- * used at runtime in Stripes, but is used by the {...@link SiteStructureTool}
to collect and
- * report on information about ActionBeans.
- *
- * @author Tim Fennell
- * @since Stripes 1.1.2
- */
-public class EventInfo {
- private String name;
- private String methodName;
- private boolean defaultEvent;
- private Collection<String> resolutions = new ArrayList<String>();
-
- /** The name of the event (possibly null in the case of default events). */
- public String getName() { return name; }
-
- /** The name of the event (possibly null in the case of default events). */
- public void setName(String name) { this.name = name; }
-
- /** The name of the method in the ActionBean that handles the event. */
- public String getMethodName() { return methodName; }
-
- /** The name of the method in the ActionBean that handles the event. */
- public void setMethodName(String methodName) { this.methodName =
methodName; }
-
- /** True if the event is the default event for the ActionBean, false
otherwise. */
- public boolean isDefaultEvent() { return defaultEvent; }
-
- /** True if the event is the default event for the ActionBean, false
otherwise. */
- public void setDefaultEvent(boolean defaultEvent) { this.defaultEvent =
defaultEvent; }
-
- /** Adds a resolution to the set of possible resolutions for the event. */
- public void addResolution(String outcome) { this.resolutions.add(outcome);
}
-
- /** The set of all possible resolutions for the event. */
- public Collection<String> getResolutions() { return resolutions; }
-
- /** The set of all possible resolutions for the event. */
- public void setResolutions(Collection<String> resolutions) {
this.resolutions = resolutions; }
-}
Copied: branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java
(from rev 1050,
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java)
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java
(rev 0)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/EventInfo.java
2009-03-03 03:58:40 UTC (rev 1090)
@@ -0,0 +1,60 @@
+/* Copyright 2005-2006 Tim Fennell
+ *
+ * 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.sourceforge.stripes.tools;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Encapsulates meta-information about a single event within an ActionBean.
This class is not
+ * used at runtime in Stripes, but is used by the {...@link SiteStructureTool}
to collect and
+ * report on information about ActionBeans.
+ *
+ * @author Tim Fennell
+ * @since Stripes 1.1.2
+ */
+public class EventInfo {
+ private String name;
+ private String methodName;
+ private boolean defaultEvent;
+ private Collection<String> resolutions = new ArrayList<String>();
+
+ /** The name of the event (possibly null in the case of default events). */
+ public String getName() { return name; }
+
+ /** The name of the event (possibly null in the case of default events). */
+ public void setName(String name) { this.name = name; }
+
+ /** The name of the method in the ActionBean that handles the event. */
+ public String getMethodName() { return methodName; }
+
+ /** The name of the method in the ActionBean that handles the event. */
+ public void setMethodName(String methodName) { this.methodName =
methodName; }
+
+ /** True if the event is the default event for the ActionBean, false
otherwise. */
+ public boolean isDefaultEvent() { return defaultEvent; }
+
+ /** True if the event is the default event for the ActionBean, false
otherwise. */
+ public void setDefaultEvent(boolean defaultEvent) { this.defaultEvent =
defaultEvent; }
+
+ /** Adds a resolution to the set of possible resolutions for the event. */
+ public void addResolution(String outcome) { this.resolutions.add(outcome);
}
+
+ /** The set of all possible resolutions for the event. */
+ public Collection<String> getResolutions() { return resolutions; }
+
+ /** The set of all possible resolutions for the event. */
+ public void setResolutions(Collection<String> resolutions) {
this.resolutions = resolutions; }
+}
Deleted:
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java
===================================================================
---
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java
2009-02-25 20:33:11 UTC (rev 1050)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java
2009-03-03 03:58:40 UTC (rev 1090)
@@ -1,423 +0,0 @@
-/* Copyright 2005-2006 Tim Fennell
- *
- * 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.sourceforge.stripes.tools;
-
-import com.sun.mirror.apt.AnnotationProcessor;
-import com.sun.mirror.apt.AnnotationProcessorEnvironment;
-import com.sun.mirror.apt.AnnotationProcessorFactory;
-import com.sun.mirror.declaration.AnnotationTypeDeclaration;
-import com.sun.mirror.declaration.ClassDeclaration;
-import com.sun.mirror.declaration.Declaration;
-import com.sun.mirror.declaration.MethodDeclaration;
-import net.sourceforge.stripes.action.DefaultHandler;
-import net.sourceforge.stripes.action.HandlesEvent;
-import net.sourceforge.stripes.action.UrlBinding;
-import net.sourceforge.stripes.exception.StripesRuntimeException;
-import net.sourceforge.stripes.util.Literal;
-
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * <p>A tool for extracting and documenting information related to the site
structure of a
- * Stripes application. SiteStructureTool is an <tt>AnnotationProcessor</tt>
(and it's own
- * factory) for use with <tt>apt</tt>, the Annotation Processing Tool. It is
capable of processing
- * several of the annotations used with Stripes to extract information about
what bean is bound
- * to which URL, the set of events handled and the possible resolutions. This
information can
- * then be printed to the screen, or output to a file in either text or xml
format.</p>
- *
- * <p>The SiteStructureTool can be run through the command line, though it is
somewhat awkward with
- * a large number of files, or a large classpath - it's command line is
extremely similar to javac.
- * A command line might look like this:</p>
- *
- *<pre>
- * apt -classpath $CLASSPATH -nocompile \
- * -factory net.sourceforge.stripes.tools.SiteStructureTool \
- * -Astripes.output.file=sitemap.txt \
- * -Astripes.output.format=text \
- * src/net/sourceforge/stripes/examples/bugzooky/web/*.java
- *</pre>
- *
- * <p>SiteStructureTool modifies its behaviour based on two options. (Custom
options are always
- * passed to apt prefixed with <tt>-A</tt>). The first is
<tt>stripes.output.file</tt>. This
- * names the file into which the output will be written. If this option is
omitted then the output
- * is simply printed to the screen. The second option is
<tt>stripes.output.format</tt> which
- * controls (not surprisingly) the output format. Valid values are 'text' and
'xml'. If this
- * value is omitted the default format is 'text' <i>unless</i> a filename is
supplied which ends in
- * '.xml', in which case xml output will be produced.</p>
- *
- * <p>The easiest way to run the SiteStructureTool is with ant. Unfortunately
the latest release
- * of ant at the time of writing does not yet include an apt task. When it
does, running apt
- * through ant should become much simpler. Until then, you can run apt using
an ant target like
- * the example below:</p>
- *
- *<pre>
- * <target name="apt" depends="compile">
- * <pathconvert property="cp" refid="build.class.path"/>
- * <path id="srcfiles">
- * <fileset dir="${src.dir}" includes="**‍/*.java"/>
- * </path>
- * <pathconvert property="srcfiles" refid="srcfiles" pathsep=" "/>
- * <exec executable="apt">
- * <arg line="-classpath ${cp} -nocompile"/>
- * <arg line="-factory
net.sourceforge.stripes.tools.SiteStructureTool"/>
- * <arg line="-Astripes.output.file=sitemap.xml"/>
- * <arg line="${srcfiles}"/>
- * </exec>
- * </target>
- *</pre>
- *
- * @author Tim Fennell
- * @since Stripes 1.1.2
- */
-public class SiteStructureTool implements AnnotationProcessor,
AnnotationProcessorFactory {
- /** Option name that controls the output format of the annotation
processor. */
- public static final String FORMAT_PARAM = "-Astripes.output.format";
-
- /** Option name that controls the file to which output is written. */
- public static final String FILE_PARAM = "-Astripes.output.file";
-
- /** Regular expression used to parse out return statements from a chunk of
java source. */
- protected static final Pattern RETURN_PATTERN =
Pattern.compile("return\\s+(new\\s+)?([^;]+);");
-
- private Set<AnnotationTypeDeclaration> typeDeclarations;
- private AnnotationProcessorEnvironment environment;
- private Map<String,ActionBeanInfo> infos = new
TreeMap<String,ActionBeanInfo>();
-
- /**
- * AnnotationProcessorFactory interface method that returns the set of
custom options
- * that are supported. Currently returns the file name and format type
parameter names.
- */
- public Collection<String> supportedOptions() {
- return Literal.set(FORMAT_PARAM, FILE_PARAM);
- }
-
- /**
- * AnnotationProcessorFactory interface method that returns the set of
annotation class
- * names that are supported. Currently returns the fully qualified names
of the following
- * annotations: @UrlBinding, @DefaultHandler, @HandlesEvent.
- */
- public Collection<String> supportedAnnotationTypes() {
- return Literal.set(DefaultHandler.class.getName(),
- HandlesEvent.class.getName(),
- UrlBinding.class.getName());
- }
-
- /**
- * AnnotationProcessorFactory interface method that returns the
SiteStructure annotation
- * processor. In reality all this method does is return the instance of
the factory
- * on which it is invoked because the SiteStructureTool is both the
factory and the processor.
- */
- public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration>
set,
- AnnotationProcessorEnvironment
env) {
- this.typeDeclarations = set;
- this.environment = env;
- return this;
- }
-
- /**
- * AnnotationProcessor interface method that is invoked to perform the
processing of the
- * annotations discovered. Builds up a set of information about the
ActionBeans discovered
- * and then prints it out according to the options passed in.
- */
- public void process() {
- // Process the URL Bindings First
- AnnotationTypeDeclaration typeDec =
getTypeDeclaration(UrlBinding.class);
- Collection<Declaration> declarations =
this.environment.getDeclarationsAnnotatedWith(typeDec);
- processUrlBindings(declarations);
-
- // Then the method level annotations
- typeDec = getTypeDeclaration(DefaultHandler.class);
- declarations = new HashSet<Declaration>();
-
declarations.addAll(this.environment.getDeclarationsAnnotatedWith(typeDec));
- typeDec = getTypeDeclaration(HandlesEvent.class);
-
declarations.addAll(this.environment.getDeclarationsAnnotatedWith(typeDec));
- processHandlerAnnotations(declarations);
-
- // Now decide where to put our output
- PrintStream out = null;
- String filename = getOption(FILE_PARAM);
-
- if (filename == null) {
- out = System.out;
- }
- else {
- try {
- out = new PrintStream(filename);
- }
- catch (FileNotFoundException fnfe) {
- throw new StripesRuntimeException("Could not open the
requested output file " +
- "for writing. Please check that file '" + filename + "'
can be created " +
- "and/or written to.", fnfe);
- }
- }
-
- // And in what format
- String format = getOption(FORMAT_PARAM);
- if (format == null) {
- if (filename != null && filename.endsWith("xml")) {
- format = "xml";
- }
- else {
- format = "text";
- }
- }
-
- // And then finally print out the output
- if ("text".equals(format)) {
- printTextFormat(out);
- }
- else if ("xml".equals(format)) {
- printXmlFormat(out);
- }
- else {
- throw new StripesRuntimeException("Unknown format requested: " +
format + ". " +
- "Supported formats are 'text' and 'xml'.");
- }
- }
-
- /**
- * For the named option to apt, returns the value of the option if it was
supplied, or
- * null if the option was not supplied.
- */
- protected String getOption(String name) {
- for (String option : this.environment.getOptions().keySet()) {
- if (option.startsWith(name)) {
- return option.split("=")[1];
- }
- }
-
- return null;
- }
-
- /**
- * Responsible for iterating through the collection of UrlBinding
annotations and
- * adding information to the instance level map of class names to
ActionBeanInfo objects.
- *
- * @param declarations a collection of Declarations annotated with
UrlBinding.
- */
- protected void processUrlBindings(Collection<Declaration> declarations) {
- for (Declaration declaration : declarations) {
- ClassDeclaration classDec = (ClassDeclaration) declaration;
-
- ActionBeanInfo info = new ActionBeanInfo();
- info.setClassName(classDec.getQualifiedName());
- info.setUrlBinding(classDec.getAnnotation(UrlBinding.class));
- this.infos.put(info.getClassName(), info);
- }
- }
-
- /**
- * Responsible for iterating through the collection of declarations
annotated with
- * either @DefaultHandler, @HandlesEvent or both. Finds the relevant
ActionBeanInfo object
- * in the instance level map and adds the event information to it.
- *
- * @param declarations a collection of Declarations annotated with handler
annotations.
- */
- protected void processHandlerAnnotations(Collection<Declaration>
declarations) {
- for (Declaration declaration : declarations) {
- MethodDeclaration methodDec = (MethodDeclaration) declaration;
- ClassDeclaration classDec = (ClassDeclaration)
methodDec.getDeclaringType();
-
- EventInfo event = new EventInfo();
- event.setMethodName(methodDec.getSimpleName());
-
- DefaultHandler defaultHandler =
methodDec.getAnnotation(DefaultHandler.class);
- if (defaultHandler != null) {
- event.setDefaultEvent(true);
- }
-
- HandlesEvent handlesEvent =
methodDec.getAnnotation(HandlesEvent.class);
- if (handlesEvent != null) {
- event.setName(handlesEvent.value());
- }
-
- // Now find the resolutions and add those to the event info
- SortedSet<String> resolutions = getResolutions(methodDec);
- event.setResolutions(resolutions);
-
- ActionBeanInfo info = this.infos.get(classDec.getQualifiedName());
- info.addEvent(event);
- }
- }
-
-
- /**
- * Prints out the accumulated information in text format to the supplied
print stream. This
- * produces a fairly human readable format that is not designed to be
machine processed.
- */
- protected void printTextFormat(PrintStream out) {
- for (ActionBeanInfo info : this.infos.values()) {
- out.println("URL: " + info.getUrlBinding().value());
- out.println(" ActionBean: " + info.getClassName());
-
- printTextEvent(out, info.getDefaultEvent());
- for (EventInfo event : info.getEvents().values()) {
- printTextEvent(out, event);
- }
-
out.println("--------------------------------------------------------------");
- }
- }
-
- /** Prints out a single event mapping in text format. Used by
printTextFormat(). */
- protected void printTextEvent(PrintStream out, EventInfo event) {
- if (event != null) {
- out.print(" Event: ");
- out.print( (event.getName() == null) ? "<no name>" :
event.getName() );
- out.println( event.isDefaultEvent() ? " (Default)" : "");
-
- for (String resolution : event.getResolutions()) {
- out.println(" Resolution: " + resolution);
- }
- }
- }
-
- /** Prints out the accumulated information in XML format. */
- protected void printXmlFormat(PrintStream out) {
- out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- out.println();
- out.println("<stripes-application>");
-
- for (ActionBeanInfo info : this.infos.values()) {
- out.print(" <action-bean class=\"");
- out.print(info.getClassName());
- out.print("\" url-binding=\"");
- out.print(info.getUrlBinding().value());
- out.println("\">");
-
- // print out the events for this action bean
- printXmlEvent(out, info.getDefaultEvent());
- for (EventInfo event : info.getEvents().values()) {
- printXmlEvent(out, event);
- }
-
- out.println(" </action-bean>");
- }
-
- out.println("</stripes-application>");
- }
-
- protected void printXmlEvent(PrintStream out, EventInfo event) {
- if (event != null) {
- out.print(" <event name=\"");
- out.print( (event.getName() == null) ? "" : event.getName() );
- out.print("\" default=\"");
- out.print(event.isDefaultEvent());
- out.println("\">");
-
- for (String resolution : event.getResolutions()) {
- out.print(" <resolution>");
- out.print(resolution);
- out.println("</resolution>");
- }
-
- out.println(" </event>");
- }
- }
-
- /**
- * Examines the set of AnnotationTypeDeclarations that this annotation
processor was
- * constructed with to locate the one representing the annotation class
provided.
- *
- * @return the matching AnnotationTypeDeclaration or null if one was not
found.
- */
- AnnotationTypeDeclaration getTypeDeclaration(Class<? extends Annotation>
type) {
- for (AnnotationTypeDeclaration declaration : this.typeDeclarations) {
- if (declaration.getQualifiedName().equals(type.getName())) {
- return declaration;
- }
- }
-
- return null;
- }
-
- /**
- * Attempts to return the code associated with the block/unit of code that
the declaration
- * represents. This is done using some fairly basic rules, and is prone
to error when
- * unmatched braces occur in comments, strings etc. This will also fail if
for some reason
- * the source file is not readable.
- *
- * @param declaration
- */
- private String getCodeFragment(Declaration declaration) {
- try {
- BufferedReader br = new BufferedReader(new
FileReader(declaration.getPosition().file()));
- StringBuilder sb = new StringBuilder(512);
-
- // Skip ahead in the source file to the start position of the
declaration
- int start = declaration.getPosition().line();
- for (int i=1; i<start; i++) {
- br.readLine();
- }
-
- // Read all the characters until we pass an open brace, and then a
matching close brace
- int ch;
- int braceCount = 0;
- boolean done = false;
-
- while (!done && (ch = br.read()) != -1) {
- sb.appendCodePoint(ch);
- if (ch=='{') {
- braceCount++;
- }
- else if (ch=='}') {
- braceCount--;
- done = braceCount == 0;
- }
- }
-
- return sb.toString();
- }
- catch (IOException ioe) {
- throw new RuntimeException("Ecountered an IOException while trying
to read a " +
- "fragment of source file: " +
declaration.getPosition().file(), ioe);
- }
- }
-
- /**
- * Fetches the code fragment associated with a method, and scans it for
return statements
- * that pass back resolutions.
- *
- * @param declaration a Declaration, usually representing a method
- * @return a sorted set of Strings representing each resolution
- */
- SortedSet<String> getResolutions(Declaration declaration) {
- String codeFragment = getCodeFragment(declaration);
- Matcher matcher = RETURN_PATTERN.matcher(codeFragment);
- SortedSet<String> resolutions = new TreeSet<String>();
-
- while(!matcher.hitEnd()) {
- if (matcher.find()) {
- resolutions.add(matcher.group(2));
- }
- }
-
- return resolutions;
- }
-
-}
Copied:
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java
(from rev 1050,
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java)
===================================================================
---
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java
(rev 0)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/SiteStructureTool.java
2009-03-03 03:58:40 UTC (rev 1090)
@@ -0,0 +1,423 @@
+/* Copyright 2005-2006 Tim Fennell
+ *
+ * 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.sourceforge.stripes.tools;
+
+import com.sun.mirror.apt.AnnotationProcessor;
+import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import com.sun.mirror.apt.AnnotationProcessorFactory;
+import com.sun.mirror.declaration.AnnotationTypeDeclaration;
+import com.sun.mirror.declaration.ClassDeclaration;
+import com.sun.mirror.declaration.Declaration;
+import com.sun.mirror.declaration.MethodDeclaration;
+import net.sourceforge.stripes.action.DefaultHandler;
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.UrlBinding;
+import net.sourceforge.stripes.exception.StripesRuntimeException;
+import net.sourceforge.stripes.util.Literal;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * <p>A tool for extracting and documenting information related to the site
structure of a
+ * Stripes application. SiteStructureTool is an <tt>AnnotationProcessor</tt>
(and it's own
+ * factory) for use with <tt>apt</tt>, the Annotation Processing Tool. It is
capable of processing
+ * several of the annotations used with Stripes to extract information about
what bean is bound
+ * to which URL, the set of events handled and the possible resolutions. This
information can
+ * then be printed to the screen, or output to a file in either text or xml
format.</p>
+ *
+ * <p>The SiteStructureTool can be run through the command line, though it is
somewhat awkward with
+ * a large number of files, or a large classpath - it's command line is
extremely similar to javac.
+ * A command line might look like this:</p>
+ *
+ *<pre>
+ * apt -classpath $CLASSPATH -nocompile \
+ * -factory net.sourceforge.stripes.tools.SiteStructureTool \
+ * -Astripes.output.file=sitemap.txt \
+ * -Astripes.output.format=text \
+ * src/net/sourceforge/stripes/examples/bugzooky/web/*.java
+ *</pre>
+ *
+ * <p>SiteStructureTool modifies its behaviour based on two options. (Custom
options are always
+ * passed to apt prefixed with <tt>-A</tt>). The first is
<tt>stripes.output.file</tt>. This
+ * names the file into which the output will be written. If this option is
omitted then the output
+ * is simply printed to the screen. The second option is
<tt>stripes.output.format</tt> which
+ * controls (not surprisingly) the output format. Valid values are 'text' and
'xml'. If this
+ * value is omitted the default format is 'text' <i>unless</i> a filename is
supplied which ends in
+ * '.xml', in which case xml output will be produced.</p>
+ *
+ * <p>The easiest way to run the SiteStructureTool is with ant. Unfortunately
the latest release
+ * of ant at the time of writing does not yet include an apt task. When it
does, running apt
+ * through ant should become much simpler. Until then, you can run apt using
an ant target like
+ * the example below:</p>
+ *
+ *<pre>
+ * <target name="apt" depends="compile">
+ * <pathconvert property="cp" refid="build.class.path"/>
+ * <path id="srcfiles">
+ * <fileset dir="${src.dir}" includes="**‍/*.java"/>
+ * </path>
+ * <pathconvert property="srcfiles" refid="srcfiles" pathsep=" "/>
+ * <exec executable="apt">
+ * <arg line="-classpath ${cp} -nocompile"/>
+ * <arg line="-factory
net.sourceforge.stripes.tools.SiteStructureTool"/>
+ * <arg line="-Astripes.output.file=sitemap.xml"/>
+ * <arg line="${srcfiles}"/>
+ * </exec>
+ * </target>
+ *</pre>
+ *
+ * @author Tim Fennell
+ * @since Stripes 1.1.2
+ */
+public class SiteStructureTool implements AnnotationProcessor,
AnnotationProcessorFactory {
+ /** Option name that controls the output format of the annotation
processor. */
+ public static final String FORMAT_PARAM = "-Astripes.output.format";
+
+ /** Option name that controls the file to which output is written. */
+ public static final String FILE_PARAM = "-Astripes.output.file";
+
+ /** Regular expression used to parse out return statements from a chunk of
java source. */
+ protected static final Pattern RETURN_PATTERN =
Pattern.compile("return\\s+(new\\s+)?([^;]+);");
+
+ private Set<AnnotationTypeDeclaration> typeDeclarations;
+ private AnnotationProcessorEnvironment environment;
+ private Map<String,ActionBeanInfo> infos = new
TreeMap<String,ActionBeanInfo>();
+
+ /**
+ * AnnotationProcessorFactory interface method that returns the set of
custom options
+ * that are supported. Currently returns the file name and format type
parameter names.
+ */
+ public Collection<String> supportedOptions() {
+ return Literal.set(FORMAT_PARAM, FILE_PARAM);
+ }
+
+ /**
+ * AnnotationProcessorFactory interface method that returns the set of
annotation class
+ * names that are supported. Currently returns the fully qualified names
of the following
+ * annotations: @UrlBinding, @DefaultHandler, @HandlesEvent.
+ */
+ public Collection<String> supportedAnnotationTypes() {
+ return Literal.set(DefaultHandler.class.getName(),
+ HandlesEvent.class.getName(),
+ UrlBinding.class.getName());
+ }
+
+ /**
+ * AnnotationProcessorFactory interface method that returns the
SiteStructure annotation
+ * processor. In reality all this method does is return the instance of
the factory
+ * on which it is invoked because the SiteStructureTool is both the
factory and the processor.
+ */
+ public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration>
set,
+ AnnotationProcessorEnvironment
env) {
+ this.typeDeclarations = set;
+ this.environment = env;
+ return this;
+ }
+
+ /**
+ * AnnotationProcessor interface method that is invoked to perform the
processing of the
+ * annotations discovered. Builds up a set of information about the
ActionBeans discovered
+ * and then prints it out according to the options passed in.
+ */
+ public void process() {
+ // Process the URL Bindings First
+ AnnotationTypeDeclaration typeDec =
getTypeDeclaration(UrlBinding.class);
+ Collection<Declaration> declarations =
this.environment.getDeclarationsAnnotatedWith(typeDec);
+ processUrlBindings(declarations);
+
+ // Then the method level annotations
+ typeDec = getTypeDeclaration(DefaultHandler.class);
+ declarations = new HashSet<Declaration>();
+
declarations.addAll(this.environment.getDeclarationsAnnotatedWith(typeDec));
+ typeDec = getTypeDeclaration(HandlesEvent.class);
+
declarations.addAll(this.environment.getDeclarationsAnnotatedWith(typeDec));
+ processHandlerAnnotations(declarations);
+
+ // Now decide where to put our output
+ PrintStream out = null;
+ String filename = getOption(FILE_PARAM);
+
+ if (filename == null) {
+ out = System.out;
+ }
+ else {
+ try {
+ out = new PrintStream(filename);
+ }
+ catch (FileNotFoundException fnfe) {
+ throw new StripesRuntimeException("Could not open the
requested output file " +
+ "for writing. Please check that file '" + filename + "'
can be created " +
+ "and/or written to.", fnfe);
+ }
+ }
+
+ // And in what format
+ String format = getOption(FORMAT_PARAM);
+ if (format == null) {
+ if (filename != null && filename.endsWith("xml")) {
+ format = "xml";
+ }
+ else {
+ format = "text";
+ }
+ }
+
+ // And then finally print out the output
+ if ("text".equals(format)) {
+ printTextFormat(out);
+ }
+ else if ("xml".equals(format)) {
+ printXmlFormat(out);
+ }
+ else {
+ throw new StripesRuntimeException("Unknown format requested: " +
format + ". " +
+ "Supported formats are 'text' and 'xml'.");
+ }
+ }
+
+ /**
+ * For the named option to apt, returns the value of the option if it was
supplied, or
+ * null if the option was not supplied.
+ */
+ protected String getOption(String name) {
+ for (String option : this.environment.getOptions().keySet()) {
+ if (option.startsWith(name)) {
+ return option.split("=")[1];
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Responsible for iterating through the collection of UrlBinding
annotations and
+ * adding information to the instance level map of class names to
ActionBeanInfo objects.
+ *
+ * @param declarations a collection of Declarations annotated with
UrlBinding.
+ */
+ protected void processUrlBindings(Collection<Declaration> declarations) {
+ for (Declaration declaration : declarations) {
+ ClassDeclaration classDec = (ClassDeclaration) declaration;
+
+ ActionBeanInfo info = new ActionBeanInfo();
+ info.setClassName(classDec.getQualifiedName());
+ info.setUrlBinding(classDec.getAnnotation(UrlBinding.class));
+ this.infos.put(info.getClassName(), info);
+ }
+ }
+
+ /**
+ * Responsible for iterating through the collection of declarations
annotated with
+ * either @DefaultHandler, @HandlesEvent or both. Finds the relevant
ActionBeanInfo object
+ * in the instance level map and adds the event information to it.
+ *
+ * @param declarations a collection of Declarations annotated with handler
annotations.
+ */
+ protected void processHandlerAnnotations(Collection<Declaration>
declarations) {
+ for (Declaration declaration : declarations) {
+ MethodDeclaration methodDec = (MethodDeclaration) declaration;
+ ClassDeclaration classDec = (ClassDeclaration)
methodDec.getDeclaringType();
+
+ EventInfo event = new EventInfo();
+ event.setMethodName(methodDec.getSimpleName());
+
+ DefaultHandler defaultHandler =
methodDec.getAnnotation(DefaultHandler.class);
+ if (defaultHandler != null) {
+ event.setDefaultEvent(true);
+ }
+
+ HandlesEvent handlesEvent =
methodDec.getAnnotation(HandlesEvent.class);
+ if (handlesEvent != null) {
+ event.setName(handlesEvent.value());
+ }
+
+ // Now find the resolutions and add those to the event info
+ SortedSet<String> resolutions = getResolutions(methodDec);
+ event.setResolutions(resolutions);
+
+ ActionBeanInfo info = this.infos.get(classDec.getQualifiedName());
+ info.addEvent(event);
+ }
+ }
+
+
+ /**
+ * Prints out the accumulated information in text format to the supplied
print stream. This
+ * produces a fairly human readable format that is not designed to be
machine processed.
+ */
+ protected void printTextFormat(PrintStream out) {
+ for (ActionBeanInfo info : this.infos.values()) {
+ out.println("URL: " + info.getUrlBinding().value());
+ out.println(" ActionBean: " + info.getClassName());
+
+ printTextEvent(out, info.getDefaultEvent());
+ for (EventInfo event : info.getEvents().values()) {
+ printTextEvent(out, event);
+ }
+
out.println("--------------------------------------------------------------");
+ }
+ }
+
+ /** Prints out a single event mapping in text format. Used by
printTextFormat(). */
+ protected void printTextEvent(PrintStream out, EventInfo event) {
+ if (event != null) {
+ out.print(" Event: ");
+ out.print( (event.getName() == null) ? "<no name>" :
event.getName() );
+ out.println( event.isDefaultEvent() ? " (Default)" : "");
+
+ for (String resolution : event.getResolutions()) {
+ out.println(" Resolution: " + resolution);
+ }
+ }
+ }
+
+ /** Prints out the accumulated information in XML format. */
+ protected void printXmlFormat(PrintStream out) {
+ out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ out.println();
+ out.println("<stripes-application>");
+
+ for (ActionBeanInfo info : this.infos.values()) {
+ out.print(" <action-bean class=\"");
+ out.print(info.getClassName());
+ out.print("\" url-binding=\"");
+ out.print(info.getUrlBinding().value());
+ out.println("\">");
+
+ // print out the events for this action bean
+ printXmlEvent(out, info.getDefaultEvent());
+ for (EventInfo event : info.getEvents().values()) {
+ printXmlEvent(out, event);
+ }
+
+ out.println(" </action-bean>");
+ }
+
+ out.println("</stripes-application>");
+ }
+
+ protected void printXmlEvent(PrintStream out, EventInfo event) {
+ if (event != null) {
+ out.print(" <event name=\"");
+ out.print( (event.getName() == null) ? "" : event.getName() );
+ out.print("\" default=\"");
+ out.print(event.isDefaultEvent());
+ out.println("\">");
+
+ for (String resolution : event.getResolutions()) {
+ out.print(" <resolution>");
+ out.print(resolution);
+ out.println("</resolution>");
+ }
+
+ out.println(" </event>");
+ }
+ }
+
+ /**
+ * Examines the set of AnnotationTypeDeclarations that this annotation
processor was
+ * constructed with to locate the one representing the annotation class
provided.
+ *
+ * @return the matching AnnotationTypeDeclaration or null if one was not
found.
+ */
+ AnnotationTypeDeclaration getTypeDeclaration(Class<? extends Annotation>
type) {
+ for (AnnotationTypeDeclaration declaration : this.typeDeclarations) {
+ if (declaration.getQualifiedName().equals(type.getName())) {
+ return declaration;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Attempts to return the code associated with the block/unit of code that
the declaration
+ * represents. This is done using some fairly basic rules, and is prone
to error when
+ * unmatched braces occur in comments, strings etc. This will also fail if
for some reason
+ * the source file is not readable.
+ *
+ * @param declaration
+ */
+ private String getCodeFragment(Declaration declaration) {
+ try {
+ BufferedReader br = new BufferedReader(new
FileReader(declaration.getPosition().file()));
+ StringBuilder sb = new StringBuilder(512);
+
+ // Skip ahead in the source file to the start position of the
declaration
+ int start = declaration.getPosition().line();
+ for (int i=1; i<start; i++) {
+ br.readLine();
+ }
+
+ // Read all the characters until we pass an open brace, and then a
matching close brace
+ int ch;
+ int braceCount = 0;
+ boolean done = false;
+
+ while (!done && (ch = br.read()) != -1) {
+ sb.appendCodePoint(ch);
+ if (ch=='{') {
+ braceCount++;
+ }
+ else if (ch=='}') {
+ braceCount--;
+ done = braceCount == 0;
+ }
+ }
+
+ return sb.toString();
+ }
+ catch (IOException ioe) {
+ throw new RuntimeException("Ecountered an IOException while trying
to read a " +
+ "fragment of source file: " +
declaration.getPosition().file(), ioe);
+ }
+ }
+
+ /**
+ * Fetches the code fragment associated with a method, and scans it for
return statements
+ * that pass back resolutions.
+ *
+ * @param declaration a Declaration, usually representing a method
+ * @return a sorted set of Strings representing each resolution
+ */
+ SortedSet<String> getResolutions(Declaration declaration) {
+ String codeFragment = getCodeFragment(declaration);
+ Matcher matcher = RETURN_PATTERN.matcher(codeFragment);
+ SortedSet<String> resolutions = new TreeSet<String>();
+
+ while(!matcher.hitEnd()) {
+ if (matcher.find()) {
+ resolutions.add(matcher.group(2));
+ }
+ }
+
+ return resolutions;
+ }
+
+}
Deleted: branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html
2009-02-25 20:33:11 UTC (rev 1050)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html
2009-03-03 03:58:40 UTC (rev 1090)
@@ -1,3 +0,0 @@
-<body>
- <p>Command line tools used in conjunction with Stripes.</p>
-</body>
\ No newline at end of file
Copied: branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html
(from rev 1050,
branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html)
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html
(rev 0)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/tools/package.html
2009-03-03 03:58:40 UTC (rev 1090)
@@ -0,0 +1,3 @@
+<body>
+ <p>Command line tools used in conjunction with Stripes.</p>
+</body>
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development