diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/ArtifactType.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/ArtifactType.java deleted file mode 100644 index 0bb6b7d05cc2e4ff60b724592d73c69c1752754c..0000000000000000000000000000000000000000 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/ArtifactType.java +++ /dev/null @@ -1,59 +0,0 @@ -/* 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 org.activiti.cycle; - -import java.util.List; - -import org.activiti.cycle.action.DownloadContentAction; -import org.activiti.cycle.action.ParameterizedAction; -import org.activiti.cycle.action.RepositoryArtifactOpenLinkAction; - -/** - * The type specifies the type of an artifact, e.g. Signavio model, jpdl process - * model, text file, word document, ... - * - * Linked to this type {@link ContentRepresentationDefinition}s for the GUI and - * {@link ArtifactAction}s are defined. - * - * TODO: Think about hierarchy - * - * @author bernd.ruecker@camunda.com - */ -public interface ArtifactType { - - public String getId(); - - public MimeType getMimeType(); - - /** - * list of {@link ContentRepresentation} in the configured order - */ - public List getContentRepresentations(); - - public ContentRepresentation getContentRepresentation(String id); - - public ContentRepresentation getDefaultContentRepresentation(); - - public ContentProvider getContentProvider(String contentRepresentationId); - - public List getParameterizedActions(); - - public ParameterizedAction getParameterizedAction(String name); - - public List createOpenLinkActions(RepositoryConnector connector, RepositoryArtifact artifact); - - public List getDownloadContentActions(); - - public Long getRevision(); - -} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/ContentProvider.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/ContentProvider.java deleted file mode 100644 index bd938ff293c5db7a2bf021179bcaefaad95c5ae6..0000000000000000000000000000000000000000 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/ContentProvider.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.activiti.cycle; - - -/** - * A content provider can create content, normaly nevessary for a - * {@link ContentRepresentation} for a special {@link RepositoryArtifact} - * - * @author bernd.ruecker@camunda.com - */ -public interface ContentProvider { - - public Content createContent(RepositoryConnector connector, RepositoryArtifact artifact); - -} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/ContentRepresentation.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/ContentRepresentation.java index 9efedbdd43a3c9f1f02696b685e5c9d1247fd7f2..f3ccfc0d7829aed872764dc26f4861991a6d55f3 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/ContentRepresentation.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/ContentRepresentation.java @@ -2,7 +2,6 @@ package org.activiti.cycle; import java.io.Serializable; -import org.activiti.cycle.impl.mimetype.Mimetypes; /** * TODO: javadoc @@ -32,8 +31,7 @@ public interface ContentRepresentation extends Serializable { public Content getContent(RepositoryArtifact artifact); /** - * The {@link MimeType} of the returned content. Note: this is not necesarily - * the same mimetype as {@link #getRepositoryArtifactType().getMimeType()}. + * The {@link MimeType} of the returned content. */ public MimeType getRepresentationMimeType(); diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/CycleComponentFactory.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/CycleComponentFactory.java index 56b3d713031313400f6df03ec1299f1e6f2086ee..0bb8dd9843e4ebaa28b122a9f30d47b6a73cba5e 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/CycleComponentFactory.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/CycleComponentFactory.java @@ -4,10 +4,14 @@ import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.net.URL; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; @@ -22,6 +26,8 @@ import org.activiti.cycle.action.ParameterizedAction; import org.activiti.cycle.annotations.CycleComponent; import org.activiti.cycle.annotations.ExcludesCycleComponents; import org.activiti.cycle.annotations.Interceptors; +import org.activiti.cycle.annotations.ListAfterComponents; +import org.activiti.cycle.annotations.ListBeforeComponents; import org.activiti.cycle.context.CycleApplicationContext; import org.activiti.cycle.context.CycleContext; import org.activiti.cycle.context.CycleContextType; @@ -37,6 +43,8 @@ import org.scannotation.WarUrlFinder; /** * Factory for cycle components. Components are classes annotated by * {@link CycleComponent}. + * + * @author daniel.meyer@camunda.com */ public abstract class CycleComponentFactory { @@ -108,8 +116,9 @@ public abstract class CycleComponentFactory { private Object getComponentInstance(CycleComponentDescriptor descriptor) { guaranteeInitialization(); - if (descriptor == null) + if (descriptor == null) { throw new IllegalArgumentException("Descriptor must not be null"); + } // try to restore from context: Object instance = restoreFormContext(descriptor); @@ -173,8 +182,9 @@ public abstract class CycleComponentFactory { private Object decorateInstance(Object instanceToDecorate, Class< ? > type) { Interceptors interceptors = type.getAnnotation(Interceptors.class); - if (interceptors == null) + if (interceptors == null) { return instanceToDecorate; + } Class< ? extends Interceptor>[] interceptorClasses = interceptors.value(); if (interceptorClasses.length == 0) { return instanceToDecorate; @@ -185,7 +195,6 @@ public abstract class CycleComponentFactory { throw new RuntimeException("Cannot decorate instance '" + instanceToDecorate + "' with decorators: '" + e.getMessage() + "'.", e); } } - private Object decorateInstance(Object instanceToDecorate, Class< ? extends Interceptor>[] interceptorClasses) throws Exception { Set> interfaces = new HashSet>(); Class< ? > superClass = instanceToDecorate.getClass(); @@ -219,7 +228,6 @@ public abstract class CycleComponentFactory { componentTypes.add(CreateUrlAction.class); componentTypes.add(ParameterizedAction.class); componentTypes.add(DownloadContentAction.class); - componentTypes.add(ContentProvider.class); componentTypes.add(ContentRepresentation.class); componentTypes.add(ContentArtifactTypeTransformation.class); componentTypes.add(ContentMimeTypeTransformation.class); @@ -249,12 +257,11 @@ public abstract class CycleComponentFactory { // look for cycle components Set componentClassNames = db.getAnnotationIndex().get(CycleComponent.class.getName()); - + // TODO: check correct classpath handling - if (componentClassNames==null || componentClassNames.size()==0) { - logger.log(Level.WARNING, "Cannot find any Cycle plugins having annotation " + CycleComponent.class.getName()); - } - else { + if (componentClassNames == null || componentClassNames.size() == 0) { + logger.log(Level.WARNING, "Cannot find any Cycle plugins having annotation " + CycleComponent.class.getName()); + } else { for (String componentClassName : componentClassNames) { Class< ? > cycleComponentClass; try { @@ -267,19 +274,26 @@ public abstract class CycleComponentFactory { } } - private String registerComponent(Class< ? > cycleComponentClass) { + public static String getComponentName(Class< ? > cycleComponentClass) { CycleComponent componentAnnotation = cycleComponentClass.getAnnotation(CycleComponent.class); String name = componentAnnotation.value(); - if (name == null) + if (name == null) { name = componentAnnotation.name(); + } if (name == null || name.length() == 0) { name = cycleComponentClass.getCanonicalName(); } + return name; + } + + private String registerComponent(Class< ? > cycleComponentClass) { + String name = getComponentName(cycleComponentClass); if (descriptorRegistry.containsKey(name)) { logger.log(Level.SEVERE, "Cannot register component of type '" + cycleComponentClass + "', name '" + name + "', copmonent of type '" + descriptorRegistry.get(name) + "', has same name."); } + CycleComponent componentAnnotation = cycleComponentClass.getAnnotation(CycleComponent.class); // init component descriptor: CycleComponentDescriptor componentDescriptor = new CycleComponentDescriptor(name, componentAnnotation.context(), cycleComponentClass); descriptorRegistry.put(name, componentDescriptor); @@ -402,4 +416,5 @@ public abstract class CycleComponentFactory { } components.removeAll(excludedComponents); } + } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/CycleComponent.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/CycleComponent.java index 866f8b24a79497cdda482a6ac81b1ad03e794a1f..36cdfb6f0366d98ef38b9a52fd601614c77be857 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/CycleComponent.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/CycleComponent.java @@ -1,15 +1,76 @@ package org.activiti.cycle.annotations; +import java.awt.Desktop.Action; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.activiti.cycle.ContentRepresentation; +import org.activiti.cycle.CycleComponentFactory; +import org.activiti.cycle.MimeType; +import org.activiti.cycle.RepositoryArtifactType; +import org.activiti.cycle.RepositoryConnector; +import org.activiti.cycle.action.CreateUrlAction; +import org.activiti.cycle.action.DownloadContentAction; +import org.activiti.cycle.action.ParameterizedAction; +import org.activiti.cycle.context.CycleApplicationContext; +import org.activiti.cycle.context.CycleContext; import org.activiti.cycle.context.CycleContextType; +import org.activiti.cycle.context.CycleSessionContext; +import org.activiti.cycle.transform.ContentArtifactTypeTransformation; +import org.activiti.cycle.transform.ContentMimeTypeTransformation; /** - * An ActivitiCycle component. Components can use services such as - * {@link Interceptors}, {@link CycleConfigParameter}s ... + * Annotation for qualifying cycle components. Cycle components are ordinary + * java classes annotated with {@link CycleComponent}. Cycle components are + * discovered and managed by the {@link CycleComponentFactory}. + *

+ * Component Name
+ * A component has a name, which is added as a parameter to this annotation, see + * {@link #name()}. If no name is provided, the class name of the component is + * used. + *

+ *

+ * Component Type
+ * While cycle components are ordinary java classes some components play a + * special role in cycle. An example of such a component is a + * {@link RepositoryConnector}. If such an interface is implemented, we call the + * implemented interface the type of a cycle component. The following + * is a list of supported component types: + *

    + *
  • {@link RepositoryConnector}
  • + *
  • {@link Action} ( {@link CreateUrlAction}, {@link ParameterizedAction}, + * {@link DownloadContentAction})
  • + *
  • {@link ContentRepresentation}
  • + *
  • {@link ContentArtifactTypeTransformation}
  • + *
  • {@link ContentMimeTypeTransformation}
  • + *
  • {@link MimeType}
  • + *
  • {@link RepositoryArtifactType}
  • + *
+ *

+ *

+ * Component Context
+ * Cycle uses a simple contextual component model. Instances of components are + * stored in a {@link CycleContext}. Two different cycle contexts are supported: + *

    + *
  • {@link CycleContextType#SESSION} and the corresponding + * {@link CycleSessionContext}: the session context is a usersession-scoped + * context of which one instance per usersession is managed. Components residing + * within this context are instantiated once per user session, i.e. each + * usersession has its own instances of such components.
  • + *
  • {@link CycleContextType#APPLICATION} and the corresponding + * {@link CycleApplicationContext}: the application context is a globally + * visible context, used as a singleton-space.
  • + *
+ * The context of a cycle component is specified using the {@link #context()} + * field of this annotation. + *

+ * + * + * @see CycleComponentFactory + * @see CycleContextType + * @see Interceptors * * @author daniel.meyer@camunda.com */ @@ -17,13 +78,19 @@ import org.activiti.cycle.context.CycleContextType; @Target({ ElementType.TYPE }) public @interface CycleComponent { + /** + * @see #name() + */ String value() default ""; + /** + * The name of a component. If left blank, the classname of the annotated + * class is used. + */ String name() default ""; /** - * Optional parameter: if a {@link CycleContextType} is set, cycle will store - * instances of the corresponding component in the corresponding context. + * Optional parameter: used to set the context of the annotated component. */ CycleContextType context() default CycleContextType.NONE; diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ExcludesCycleComponents.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ExcludesCycleComponents.java index 7a74d16d1921609616c4dfa3ead7bd139af0d2ba..9c0de1f83f4af26bf590eb35d0a1b7d8ec892dd8 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ExcludesCycleComponents.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ExcludesCycleComponents.java @@ -46,6 +46,7 @@ public @interface ExcludesCycleComponents { /** * Classes of the components to exclude */ + @SuppressWarnings("rawtypes") Class[] classes() default {}; } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/Interceptors.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/Interceptors.java index eed237b314e18ddc88745351238fb10758f2d4b1..3103e97e850990fee21cb84405f437163afc8786 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/Interceptors.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/Interceptors.java @@ -5,16 +5,34 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.activiti.cycle.CycleComponentFactory; import org.activiti.cycle.impl.Interceptor; /** - * Annotate ActivityCycle components with this - * @author meyerd + * Annotation for specifying a list of interceptors for a cycle component. + * Interceptors are classes implementing the {@link Interceptor} interface. + * + *

+ * Note: the {@link CycleComponentFactory} generates proxies + * using the built-in java proxy mechanisms. Cycle component implementors must + * therefore ensure that components annotated using this annotation implement at + * least one interface which can be proxied. This is true for cycle components + * with a special component type (see {@link CycleComponent}). Also + * make sure not to cast instances of such components to the implementation type + * but to the interface. If a component implements multiple interfaces, all of + * the interfaces are proxied. + *

+ * + * @see CycleComponent + * @see CycleComponentFactory + * @see Interceptor + * + * @author daniel.meyer@camunda.com */ @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) +@Target({ ElementType.TYPE }) public @interface Interceptors { - - Class[] value(); + + Class< ? extends Interceptor>[] value(); } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ListAfterComponents.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ListAfterComponents.java new file mode 100644 index 0000000000000000000000000000000000000000..b5b67186e8030cb39339abdafbf82ee3c1e944c3 --- /dev/null +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ListAfterComponents.java @@ -0,0 +1,50 @@ +package org.activiti.cycle.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.activiti.cycle.ContentRepresentation; +import org.activiti.cycle.action.Action; +import org.activiti.cycle.action.DownloadContentAction; +import org.activiti.cycle.action.ParameterizedAction; + +/** + * Annotation used to define a sorting on components. Component instances are + * listed in various places, for example in the UI. Putting this annotation on a + * component is a hint for the cycle component infrastructure + * to attempt to list instances of this component after instances of + * the components referenced using this annotation. If this annotation is set + * for a cycle component and no parameters are given, cycle will try to list the + * corresponding component instances as first items in the list. + * + *

+ * Note: the sorting on components using {@link ListBeforeComponents} and + * {@link ListAfterComponents} is only supported above the service layer, ie. on + * component lists returned by a cycle service. + *

+ * + *

+ * Note: the sorting on components is currently only supported + * for some component types: + *

    + *
  • {@link Action} (which subsumes {@link ParameterizedAction}, + * {@link DownloadContentAction} etc...)
  • + *
  • {@link ContentRepresentation}
  • + *
+ *

+ * + * @author daniel.meyer@camunda.com + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +public @interface ListAfterComponents { + + String[] value() default {}; + + String[] names() default {}; + + @SuppressWarnings("rawtypes") + Class[] classes() default {}; +} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ListBeforeComponents.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ListBeforeComponents.java new file mode 100644 index 0000000000000000000000000000000000000000..e1fc98b588d6329836885b1a286d1bb929393b8b --- /dev/null +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/annotations/ListBeforeComponents.java @@ -0,0 +1,52 @@ +package org.activiti.cycle.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.activiti.cycle.ContentRepresentation; +import org.activiti.cycle.action.Action; +import org.activiti.cycle.action.DownloadContentAction; +import org.activiti.cycle.action.ParameterizedAction; + +/** + * Annotation used to define a sorting on components. Component instances are + * listed in various places, for example in the UI. Putting this annotation on a + * component is a hint for the cycle component infrastructure + * to attempt to list instances of this component before instances of + * the components referenced using this annotation. If this annotation is set + * for a cycle component and no parameters are given, cycle will try to list the + * corresponding component instances as first items in the list. + * + *

+ * Note: the sorting on components using + * {@link ListBeforeComponents} and {@link ListAfterComponents} is only + * supported above the service layer, ie. on component lists returned by a cycle + * service. + *

+ * + *

+ * Note: the sorting on components is currently only supported + * for some component types: + *

    + *
  • {@link Action} (which subsumes {@link ParameterizedAction}, + * {@link DownloadContentAction} etc...)
  • + *
  • {@link ContentRepresentation}
  • + *
+ *

+ * + * @author daniel.meyer@camunda.com + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +public @interface ListBeforeComponents { + + String[] value() default {}; + + String[] names() default {}; + + @SuppressWarnings("rawtypes") + Class[] classes() default {}; + +} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/AbstractArtifactActionImpl.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/AbstractArtifactActionImpl.java index 889bc9be08811b9afed4b79749a48486e962e1a5..577689dfb2a451daaa63803687bb5e4814ccfa8f 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/AbstractArtifactActionImpl.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/AbstractArtifactActionImpl.java @@ -15,7 +15,6 @@ package org.activiti.cycle.impl; import java.io.Serializable; import java.util.logging.Logger; -import org.activiti.cycle.ArtifactType; /** * The file action defines an action you can execute upon a file / artifact diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/ContentProviderImpl.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/ContentProviderImpl.java deleted file mode 100644 index 9e7d58046f1d0793a6f7a46e8e0366086576e01b..0000000000000000000000000000000000000000 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/ContentProviderImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.activiti.cycle.impl; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.logging.Logger; - -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.activiti.cycle.Content; -import org.activiti.cycle.ContentProvider; -import org.activiti.cycle.RepositoryArtifact; -import org.activiti.cycle.RepositoryConnector; -import org.activiti.cycle.RepositoryException; -import org.restlet.ext.xml.DomRepresentation; - -/** - * - * @author bernd.ruecker - */ -public abstract class ContentProviderImpl implements ContentProvider { - - protected Logger log = Logger.getLogger(this.getClass().getName()); - - public abstract void addValueToContent(Content content, RepositoryConnector connector, RepositoryArtifact artifact); - - public Content createContent(RepositoryConnector connector, RepositoryArtifact artifact) { - Content c = new Content(); - - addValueToContent(c, connector, artifact); - if (c.isNull()) { - throw new RepositoryException("No content created for artifact " + artifact.getGlobalUniqueId() + " ' by provider '" + this.getClass().getName() - + "' (was null). Please check provider or artifact."); - } - - return c; - } - - /** - * helper method to transform XML to String if required by any - * {@link ContentProvider} - */ - public String getXmlAsString(DOMSource xmlData) throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, - IOException { - StringWriter stringWriter = new StringWriter(); - StreamResult streamResult = new StreamResult(stringWriter); - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - transformer.setOutputProperty(OutputKeys.METHOD, "xml"); - transformer.transform(xmlData, streamResult); - - return stringWriter.toString(); - } - - public String getXmlAsString(DomRepresentation xmlData) throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, - IOException { - return getXmlAsString(xmlData.getDomSource()); - } - -} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/CycleComponentComparator.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/CycleComponentComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..a5e86708235e6bf9171f077f6d6c87fe349e2874 --- /dev/null +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/CycleComponentComparator.java @@ -0,0 +1,128 @@ +package org.activiti.cycle.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import org.activiti.cycle.CycleComponentFactory; +import org.activiti.cycle.annotations.ListAfterComponents; +import org.activiti.cycle.annotations.ListBeforeComponents; + +/** + * Cycle component comparator used to determine a sorting on cycle components. + * + * @author daniel.meyer@camunda.com + */ +@SuppressWarnings("rawtypes") +public class CycleComponentComparator implements Comparator { + + private Class< ? > getComponentClass(Object o) { + // TODO: naive: this does not work for decorated components. + return o.getClass(); + } + + private List getBeforeComponentNames(Class< ? > o) { + List componentNames = new ArrayList(); + ListBeforeComponents listBeforeComponents = o.getAnnotation(ListBeforeComponents.class); + if (listBeforeComponents != null) { + componentNames.addAll(Arrays.asList(listBeforeComponents.value())); + componentNames.addAll(Arrays.asList(listBeforeComponents.names())); + Class[] classes = listBeforeComponents.classes(); + for (Class clazz : classes) { + componentNames.add(clazz.getCanonicalName()); + } + } + return componentNames; + } + private List getAfterComponentNames(Class< ? > o) { + List componentNames = new ArrayList(); + ListBeforeComponents listAfterComponents = o.getAnnotation(ListBeforeComponents.class); + if (listAfterComponents != null) { + componentNames.addAll(Arrays.asList(listAfterComponents.value())); + componentNames.addAll(Arrays.asList(listAfterComponents.names())); + Class[] classes = listAfterComponents.classes(); + for (Class clazz : classes) { + componentNames.add(clazz.getCanonicalName()); + } + } + return componentNames; + } + + private boolean isAfterAll(Class< ? > componentClass) { + ListAfterComponents annotation = componentClass.getAnnotation(ListAfterComponents.class); + if (annotation != null) { + if (annotation.value().length != 0) { + return false; + } + if (annotation.names().length != 0) { + return false; + } + if (annotation.classes().length != 0) { + return false; + } + return true; + } + return false; + + } + + private boolean isBeforeAll(Class< ? > componentClass) { + ListBeforeComponents annotation = componentClass.getAnnotation(ListBeforeComponents.class); + if (annotation != null) { + if (annotation.value().length != 0) { + return false; + } + if (annotation.names().length != 0) { + return false; + } + if (annotation.classes().length != 0) { + return false; + } + return true; + } + return false; + + } + + public int compare(Object o1, Object o2) { + if (o1 == o2 || o1.equals(o2)) { + return 0; + } + Class< ? > o1ComponentClass = getComponentClass(o1); + + if (isBeforeAll(o1ComponentClass)) { + return -1; + } + if (isAfterAll(o1ComponentClass)) { + return 1; + } + Class< ? > o2ComponentClass = getComponentClass(o2); + if (isBeforeAll(o2ComponentClass)) { + return 1; + } + if (isAfterAll(o2ComponentClass)) { + return -1; + } + + String o1ComponentName = CycleComponentFactory.getComponentName(o1ComponentClass); + List o1BeforeComponentNames = getBeforeComponentNames(o1ComponentClass); + List o1AfterComponentNames = getAfterComponentNames(o1ComponentClass); + String o2ComponentName = CycleComponentFactory.getComponentName(o2ComponentClass); + List o2BeforeComponentNames = getBeforeComponentNames(o2ComponentClass); + List o2AfterComponentNames = getAfterComponentNames(o2ComponentClass); + + if (o1ComponentName.equals(o2ComponentName)) { + // TODO: what do we do with two instances of the same component? + return -1; + } + if (o1BeforeComponentNames.contains(o2ComponentName) || o2AfterComponentNames.contains(o1ComponentName)) { + return -1; + } + if (o2BeforeComponentNames.contains(o1ComponentName) || o1AfterComponentNames.contains(o2ComponentName)) { + return 1; + } + return o1.toString().compareTo(o2.toString()); + } + +} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/CycleComponentInvocationHandler.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/CycleComponentInvocationHandler.java index 1297b28f8aaa78fe652cae1a6a8d02e03065617f..ddbe8ffd2bb9d3e0e45c2499ae4f077a1a7da6ec 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/CycleComponentInvocationHandler.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/CycleComponentInvocationHandler.java @@ -25,18 +25,28 @@ public class CycleComponentInvocationHandler implements InvocationHandler { } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - + // before method invocation for (Interceptor interceptor : interceptorInstances) { - interceptor.interceptMethodCall(method, instance, args); + interceptor.beforeInvoke(method, instance, args); // throws exception } + + Object invocationResult = null; try { - return method.invoke(instance, args); + invocationResult = method.invoke(instance, args); } catch (Exception e) { + // catch the InvocationTargetException and throw the actual exception + // instead. if (e instanceof InvocationTargetException) { throw ((InvocationTargetException) e).getTargetException(); } throw e; } + // after method invocation + for (Interceptor interceptor : interceptorInstances) { + interceptor.afterInvoke(method, instance, invocationResult, args); + } + return invocationResult; + } } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/Interceptor.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/Interceptor.java index 5d971ce6285e74f4b89115c66981fac46e5fd3ac..e5b73fc0d1f60d73a3819ea33a0d88f99294cdda 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/Interceptor.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/Interceptor.java @@ -2,13 +2,50 @@ package org.activiti.cycle.impl; import java.lang.reflect.Method; +import org.activiti.cycle.CycleComponentFactory; +import org.activiti.cycle.annotations.CycleComponent; +import org.activiti.cycle.annotations.Interceptors; + /** - * Generic interceptor interface. + * Interceptor for cycle components. Supports a "before" and an "after" - + * interceptor. Declared using the {@link Interceptors} annotation. + * + * @see CycleComponent + * @see CycleComponentFactory + * @see Interceptors * * @author daniel.meyer@camunda.com */ public interface Interceptor { - void interceptMethodCall(Method m, Object object, Object... args); + /** + * Interceptor-method called before the method-invocation. Implementors can + * also block the method invocation by throwing an exception. + * + * @param m + * the Method to be invoked + * @param object + * the proxied object, the method is invoked on. + * @param args + * array of parameter objects for the method invocation (can be null) + */ + void beforeInvoke(Method m, Object object, Object... args); // TODO: throws + // Exception? + /** + * Interceptor-method called after the method-invocation. + * + * @param m + * the Method to be invoked + * @param object + * the object, the method is invoked on. + * @param invocationResult + * the object returned by the method invocation (can be null). + * @param args + * array of parameter objects for the method invocation (can be + * null). + */ + void afterInvoke(Method m, Object object, Object invocationResult, Object... args); // TODO: + // throws + // Exception? } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/ParameterizedActionImpl.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/ParameterizedActionImpl.java index 90bbb5821760aec44bc0ccbe0f8437c54af1596b..4ce22a7e8643258c0aefc3fe7d2b06faadb915a9 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/ParameterizedActionImpl.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/ParameterizedActionImpl.java @@ -54,4 +54,8 @@ public abstract class ParameterizedActionImpl extends AbstractArtifactActionImpl return value; } + @Override + public String toString() { + return getId(); + } } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/AbstractRepositoryConnector.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/AbstractRepositoryConnector.java index aa19602c5c204c4c8b2fbfefb49923d86cce6246..042b17d2fc3994ff5c21a4838734ae09570ebfbb 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/AbstractRepositoryConnector.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/AbstractRepositoryConnector.java @@ -1,10 +1,9 @@ package org.activiti.cycle.impl.connector; +import java.util.List; import java.util.Map; -import java.util.Set; import java.util.logging.Logger; -import org.activiti.cycle.ArtifactType; import org.activiti.cycle.Content; import org.activiti.cycle.RepositoryArtifact; import org.activiti.cycle.RepositoryConnector; @@ -16,77 +15,48 @@ import org.activiti.cycle.service.CycleServiceFactory; public abstract class AbstractRepositoryConnector implements RepositoryConnector { - protected Logger log = Logger.getLogger(this.getClass().getName()); + protected Logger log = Logger.getLogger(this.getClass().getName()); - private T configuration; + private T configuration; + + public AbstractRepositoryConnector(T configuration) { + this.configuration = configuration; + } - public AbstractRepositoryConnector(T configuration) { - this.configuration = configuration; - } - public AbstractRepositoryConnector() { } - public T getConfiguration() { - return configuration; - } + public T getConfiguration() { + return configuration; + } - public void setConfiguration(RepositoryConnectorConfiguration configuration) { this.configuration = (T) configuration; } - -// /** -// * Typical basic implementation to query {@link Content} from -// * {@link ContentProvider} obtained by the {@link ArtifactType} of the -// * artifact. -// */ -// public Content getContent(String artifactId, String representationName) throws RepositoryNodeNotFoundException { -// RepositoryArtifact artifact = getRepositoryArtifact(artifactId); -// return artifact.getArtifactType().getContentProvider(representationName).createContent(this, artifact); -// } - /** - * As a default a connector doesn't provide any preview picture - */ - public Content getRepositoryArtifactPreview(String artifactId) throws RepositoryNodeNotFoundException { - return null; - } + /** + * As a default a connector doesn't provide any preview picture + */ + public Content getRepositoryArtifactPreview(String artifactId) throws RepositoryNodeNotFoundException { + return null; + } - /** - * Typical basic implementation for execute a {@link ParameterizedAction} by - * loading the {@link RepositoryArtifact}, query the action via the - * {@link ArtifactType} and execute it by handing over "this" as parameter - * for the connector - */ - public void executeParameterizedAction(String artifactId, String actionId, Map parameters) throws Exception { - RepositoryArtifact artifact = getRepositoryArtifact(artifactId); - CyclePluginService pluginService = CycleServiceFactory.getCyclePluginService(); - Set actions = pluginService.getParameterizedActions(artifact); - for (ParameterizedAction parameterizedAction : actions) { - if(!parameterizedAction.getId().equals(actionId)) { + /** + * Typical basic implementation for execute a {@link ParameterizedAction} by + * loading the {@link RepositoryArtifact}, query the action via the + * {@link ArtifactType} and execute it by handing over "this" as parameter for + * the connector + */ + public void executeParameterizedAction(String artifactId, String actionId, Map parameters) throws Exception { + RepositoryArtifact artifact = getRepositoryArtifact(artifactId); + CyclePluginService pluginService = CycleServiceFactory.getCyclePluginService(); + List actions = pluginService.getParameterizedActions(artifact); + for (ParameterizedAction parameterizedAction : actions) { + if (!parameterizedAction.getId().equals(actionId)) { continue; } parameterizedAction.execute(this, artifact, parameters); } - } - -// /** -// * Basic implementation returning all registered {@link ArtifactType}s from -// * the {@link RepositoryConnectorConfiguration} -// */ -// public List getSupportedArtifactTypes(String folderId) { -// return getConfiguration().getArtifactTypes(); -// } - -// public ArtifactType getArtifactType(String id) { -// for (ArtifactType type : getConfiguration().getArtifactTypes()) { -// if (type.getId().equals(id)) { -// return type; -// } -// } -// throw new RepositoryException("ArtifactType with id '" + id + "' doesn't exist. Possible types are: " -// + getConfiguration().getArtifactTypes()); -// } + } } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/ConnectorLoginInterceptor.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/ConnectorLoginInterceptor.java index 2edac4d78d4da17c28cd83aebe23cb18d75af0e3..dcefddf0ae93769c1a25123ae0ee009627900662 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/ConnectorLoginInterceptor.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/ConnectorLoginInterceptor.java @@ -13,23 +13,31 @@ import org.activiti.cycle.impl.Interceptor; */ public class ConnectorLoginInterceptor implements Interceptor { - public void interceptMethodCall(Method m, Object object, Object... args) { + public void beforeInvoke(Method m, Object object, Object... args) { RepositoryConnector connector = (RepositoryConnector) object; if ("setConfiguration".equals(m.getName())) { + // let the invocation of the "setConfiguration"-method pass return; } if ("getConfiguration".equals(m.getName())) { + // let the invocation of the "getConfiguration"-method pass return; } if ("login".equals(m.getName())) { - // TODO: Why always return true? When is it really logged in? + // let the invocation of the "login"-method pass return; } + // for all other methods, check whether the connector is logged in. if (!connector.isLoggedIn()) { + // the connector is not logged in, block invocation throw new RepositoryAuthenticationException("Connector '" + connector.getConfiguration().getName() + "' is not logged in ", connector.getConfiguration() .getId()); } } + public void afterInvoke(Method m, Object object, Object invocationResult, Object... args) { + // do nothing + } + } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/FileSystemConnectorConfiguration.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/FileSystemConnectorConfiguration.java index 9c8924cd43caf911ee738682ea2845403b48bb8b..65588c045ed2ddbfcea24154b3c98d4bc4be60ff 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/FileSystemConnectorConfiguration.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/FileSystemConnectorConfiguration.java @@ -15,7 +15,6 @@ package org.activiti.cycle.impl.connector.fs; import java.io.File; import java.io.IOException; -import org.activiti.cycle.ArtifactType; import org.activiti.cycle.CycleComponentFactory; import org.activiti.cycle.RepositoryConnector; import org.activiti.cycle.RepositoryException; diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/FileBinaryContentProvider.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/FileBinaryContentProvider.java deleted file mode 100644 index 55a9e241e0edf09418e08cbb448706da552f64b1..0000000000000000000000000000000000000000 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/FileBinaryContentProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.activiti.cycle.impl.connector.fs.provider; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.logging.Level; - -import org.activiti.cycle.Content; -import org.activiti.cycle.RepositoryArtifact; -import org.activiti.cycle.RepositoryConnector; -import org.activiti.cycle.RepositoryException; -import org.activiti.cycle.impl.ContentProviderImpl; -import org.activiti.cycle.impl.connector.fs.FileSystemConnector; -import org.activiti.cycle.impl.util.IoUtils; - -public class FileBinaryContentProvider extends ContentProviderImpl { - @Override - public void addValueToContent(Content content, RepositoryConnector connector, RepositoryArtifact artifact) { - String fileName = ((FileSystemConnector) connector).getConfiguration().getBasePath() + artifact.getNodeId(); - File file = new File(fileName); - FileInputStream fis = null; - - try { - fis = new FileInputStream(file); - content.setValue(IoUtils.readBytes(fis)); - - } catch (FileNotFoundException fnfe) { - throw new RepositoryException("Unable to find artifact " + artifact, fnfe); - } catch (IOException ioe) { - throw new RepositoryException("Error while accessing artifact " + artifact, ioe); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException ex) { - // log but ignore exception on closing - log.log(Level.WARNING, "Couldn't close file '" + fileName + "'. Ignoring.", ex); - } - } - } - } -} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/TextFileContentProvider.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/TextFileContentProvider.java deleted file mode 100644 index eb4438d83bd29bd43e4b12f15966b7418dbf42e5..0000000000000000000000000000000000000000 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/TextFileContentProvider.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.activiti.cycle.impl.connector.fs.provider; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; - -import org.activiti.cycle.Content; -import org.activiti.cycle.RepositoryArtifact; -import org.activiti.cycle.RepositoryConnector; -import org.activiti.cycle.RepositoryException; -import org.activiti.cycle.impl.ContentProviderImpl; -import org.activiti.cycle.impl.connector.fs.FileSystemConnector; - -public class TextFileContentProvider extends ContentProviderImpl { - - @Override - public void addValueToContent(Content content, RepositoryConnector connector, RepositoryArtifact artifact) { - String fileName = ((FileSystemConnector) connector).getConfiguration().getBasePath() + artifact.getNodeId(); - File file = new File(fileName); - try{ - content.setValue(new FileInputStream(file)); - } catch (FileNotFoundException fnfe) { - throw new RepositoryException("Unable to find artifact " + artifact, fnfe); - } - } - -} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/XmlFileContentProvider.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/XmlFileContentProvider.java deleted file mode 100644 index 6afe5b9b075afe5815795d49d55f477f6d157126..0000000000000000000000000000000000000000 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/fs/provider/XmlFileContentProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.activiti.cycle.impl.connector.fs.provider; - -import java.io.File; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.dom.DOMSource; - -import org.activiti.cycle.Content; -import org.activiti.cycle.RepositoryArtifact; -import org.activiti.cycle.RepositoryConnector; -import org.activiti.cycle.RepositoryException; -import org.activiti.cycle.impl.ContentProviderImpl; -import org.activiti.cycle.impl.connector.fs.FileSystemConnector; -import org.w3c.dom.Document; - -public class XmlFileContentProvider extends ContentProviderImpl { - - @Override - public void addValueToContent(Content content, RepositoryConnector connector, RepositoryArtifact artifact) { - String fileName = ((FileSystemConnector) connector).getConfiguration().getBasePath() + artifact.getNodeId(); - File file = new File(fileName); - - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db; - db = dbf.newDocumentBuilder(); - Document doc = db.parse(file); - - content.setValue(getXmlAsString(new DOMSource(doc))); - } catch (Exception e) { - throw new RepositoryException("Error while retrieving artifact " + artifact + " as xml content", e); - } - } -} diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/SignavioConnectorConfiguration.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/SignavioConnectorConfiguration.java index f7d29a9c260c5e118f23fc0e8dc7d8d4daf1a546..8dc9f1a97faf8eea5585c022c995da957c1f34b2 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/SignavioConnectorConfiguration.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/SignavioConnectorConfiguration.java @@ -15,7 +15,6 @@ package org.activiti.cycle.impl.connector.signavio; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import org.activiti.cycle.ArtifactType; import org.activiti.cycle.CycleComponentFactory; import org.activiti.cycle.RepositoryConnector; import org.activiti.cycle.RepositoryException; diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/AbstractPngProvider.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/AbstractPngProvider.java index 783ac31edee047dfe4742d201b489d1257b92c2b..1522cab728e324566cc7e80d6145f526b86aaf09 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/AbstractPngProvider.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/AbstractPngProvider.java @@ -19,16 +19,12 @@ import org.activiti.cycle.Content; import org.activiti.cycle.MimeType; import org.activiti.cycle.RenderInfo; import org.activiti.cycle.RepositoryArtifact; -import org.activiti.cycle.RepositoryArtifactType; import org.activiti.cycle.RepositoryException; -import org.activiti.cycle.annotations.CycleComponent; import org.activiti.cycle.components.RuntimeConnectorList; import org.activiti.cycle.context.CycleApplicationContext; -import org.activiti.cycle.context.CycleContextType; import org.activiti.cycle.context.CycleSessionContext; import org.activiti.cycle.impl.connector.signavio.SignavioConnectorConfiguration; import org.activiti.cycle.impl.connector.signavio.SignavioConnectorInterface; -import org.activiti.cycle.impl.connector.signavio.repositoryartifacttype.SignavioBpmn20ArtifactType; import org.activiti.cycle.impl.mimetype.PngMimeType; public abstract class AbstractPngProvider extends SignavioContentRepresentationProvider { diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/BpmnProcessPngProvider.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/BpmnProcessPngProvider.java index 0ee27d10611e59efada9286f26023eeb33f41587..3e02f6d9bb95d2186287d68b2326503dcf1929e2 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/BpmnProcessPngProvider.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/BpmnProcessPngProvider.java @@ -2,6 +2,7 @@ package org.activiti.cycle.impl.connector.signavio.provider; import org.activiti.cycle.RepositoryArtifactType; import org.activiti.cycle.annotations.CycleComponent; +import org.activiti.cycle.annotations.ListBeforeComponents; import org.activiti.cycle.context.CycleApplicationContext; import org.activiti.cycle.context.CycleContextType; import org.activiti.cycle.impl.connector.signavio.repositoryartifacttype.SignavioBpmn20ArtifactType; @@ -12,6 +13,7 @@ import org.activiti.cycle.impl.connector.signavio.repositoryartifacttype.Signavi * @author meyerd */ @CycleComponent(context = CycleContextType.APPLICATION) +@ListBeforeComponents public class BpmnProcessPngProvider extends AbstractPngProvider { public RepositoryArtifactType getRepositoryArtifactType() { diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/DefaultPngProvider.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/DefaultPngProvider.java index 7bff211558d1bc2e8e11051c7f112a093840d14d..f93939ac632959989c89cce12f5b62ed7cf3c160 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/DefaultPngProvider.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/signavio/provider/DefaultPngProvider.java @@ -2,6 +2,7 @@ package org.activiti.cycle.impl.connector.signavio.provider; import org.activiti.cycle.RepositoryArtifactType; import org.activiti.cycle.annotations.CycleComponent; +import org.activiti.cycle.annotations.ListBeforeComponents; import org.activiti.cycle.context.CycleApplicationContext; import org.activiti.cycle.context.CycleContextType; import org.activiti.cycle.impl.connector.signavio.repositoryartifacttype.SignavioDefaultArtifactType; @@ -12,6 +13,7 @@ import org.activiti.cycle.impl.connector.signavio.repositoryartifacttype.Signavi * @author daniel.meyer@camunda.com */ @CycleComponent(context = CycleContextType.APPLICATION) +@ListBeforeComponents public class DefaultPngProvider extends AbstractPngProvider { public RepositoryArtifactType getRepositoryArtifactType() { diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/view/TagConnector.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/view/TagConnector.java index 80daf845dcd6bbecf6034bd3e36ef67350e0b5ee..e3bdb7110226136896f7578d222b77ea13c397be 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/view/TagConnector.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/connector/view/TagConnector.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.activiti.cycle.ArtifactType; import org.activiti.cycle.Content; import org.activiti.cycle.ContentRepresentation; import org.activiti.cycle.CycleTagContent; @@ -44,9 +43,6 @@ public class TagConnector implements RepositoryConnector { public void commitPendingChanges(String comment) { } - public List getSupportedArtifactTypes(String folderId) { - return new ArrayList(); - } public boolean login(String username, String password) { return true; diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CycleContentServiceImpl.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CycleContentServiceImpl.java index 59b86b5699655e619b78cbe73fc5da59c5058927..c35887fe9177d0e430e40af60cae3c2cc3808ccd 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CycleContentServiceImpl.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CycleContentServiceImpl.java @@ -2,7 +2,6 @@ package org.activiti.cycle.impl.service; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Set; @@ -13,8 +12,8 @@ import org.activiti.cycle.MimeType; import org.activiti.cycle.RepositoryArtifact; import org.activiti.cycle.RepositoryArtifactType; import org.activiti.cycle.context.CycleApplicationContext; +import org.activiti.cycle.impl.CycleComponentComparator; import org.activiti.cycle.impl.artifacttype.RepositoryArtifactTypes; -import org.activiti.cycle.impl.connector.signavio.provider.AbstractPngProvider; import org.activiti.cycle.impl.mimetype.Mimetypes; import org.activiti.cycle.impl.representation.ContentRepresentations; import org.activiti.cycle.impl.transform.Transformations; @@ -26,6 +25,7 @@ import org.activiti.cycle.transform.ContentTransformationException; * * @author daniel.meyer@camunda.com */ +@SuppressWarnings("unchecked") public class CycleContentServiceImpl implements CycleContentService { public Set getAvailableMimeTypes() { @@ -62,28 +62,10 @@ public class CycleContentServiceImpl implements CycleContentService { } private void sortContentReprsentations(List sortedList) { - // TODO: sort contentRepresentations according to name AND annotations - // TODO: move to better suited place - // for the moment: sort alphabetically and make sure that "PNG" is the first - // tab: - Collections.sort(sortedList, new Comparator() { - - public int compare(ContentRepresentation o1, ContentRepresentation o2) { - if (o1.equals(o2)) { - return 0; - } - if (AbstractPngProvider.class.isAssignableFrom(o1.getClass())) { - return -1; - } - if (AbstractPngProvider.class.isAssignableFrom(o2.getClass())) { - return 1; - } - return o1.getId().compareTo(o2.getId()); - } - }); + Collections.sort(sortedList, new CycleComponentComparator()); } - private void removeExcludedContentRepresentations(Set represenations) { + private void removeExcludedContentRepresentations(Set represenations) { CycleComponentFactory.removeExcludedComponents(represenations); } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CyclePluginServiceImpl.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CyclePluginServiceImpl.java index b9667b46b757021daf451404b7ca3dba21eebe88..ac90db5bd842fcc5b4842f07112693e758fa1132 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CyclePluginServiceImpl.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CyclePluginServiceImpl.java @@ -1,27 +1,28 @@ package org.activiti.cycle.impl.service; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.activiti.cycle.CycleComponentFactory; import org.activiti.cycle.RepositoryArtifact; import org.activiti.cycle.RepositoryArtifactType; import org.activiti.cycle.RepositoryConnector; -import org.activiti.cycle.action.Action; import org.activiti.cycle.action.ArtifactAwareParameterizedAction; import org.activiti.cycle.action.CreateUrlAction; import org.activiti.cycle.action.DownloadContentAction; import org.activiti.cycle.action.ParameterizedAction; import org.activiti.cycle.action.RepositoryArtifactOpenLinkAction; -import org.activiti.cycle.annotations.ExcludesCycleComponents; import org.activiti.cycle.components.RuntimeConnectorList; import org.activiti.cycle.context.CycleApplicationContext; import org.activiti.cycle.context.CycleSessionContext; +import org.activiti.cycle.impl.CycleComponentComparator; import org.activiti.cycle.impl.action.Actions; import org.activiti.cycle.service.CyclePluginService; -import com.sun.xml.xsom.impl.scd.Axis; - /** * Default Implementation of the {@link CyclePluginService} * @@ -42,26 +43,23 @@ public class CyclePluginServiceImpl implements CyclePluginService { return CycleApplicationContext.get(Actions.class).getDownloadContentActions(type); } - public Set getParameterizedActions(RepositoryArtifact artifact) { + public List getParameterizedActions(RepositoryArtifact artifact) { Set actions = getParameterizedActions(artifact.getArtifactType()); removeNonApplicableActions(actions, artifact); removeExcludedActions(actions); - sortActions(actions, artifact); - return actions; + return sortActions(actions, artifact); } - public Set getCreateUrlActions(RepositoryArtifact artifact) { + public List getCreateUrlActions(RepositoryArtifact artifact) { Set actions = getCreateUrlActions(artifact.getArtifactType()); removeExcludedActions(actions); - sortActions(actions, artifact); - return actions; + return sortActions(actions, artifact); } - public Set getDownloadContentActions(RepositoryArtifact artifact) { + public List getDownloadContentActions(RepositoryArtifact artifact) { Set actions = getDownloadContentActions(artifact.getArtifactType()); removeExcludedActions(actions); - sortActions(actions, artifact); - return actions; + return sortActions(actions, artifact); } private void removeNonApplicableActions(Set actions, RepositoryArtifact forArtifact) { @@ -77,8 +75,11 @@ public class CyclePluginServiceImpl implements CyclePluginService { actions.removeAll(nonApplicableActions); } - private void sortActions(Set actions, RepositoryArtifact artifact) { - // TODO + @SuppressWarnings("unchecked") + private List sortActions(Collection actions, RepositoryArtifact artifact) { + ArrayList sortedList = new ArrayList(actions); + Collections.sort(sortedList, new CycleComponentComparator()); + return sortedList; } private void removeExcludedActions(Set actions) { diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CycleRepositoryServiceImpl.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CycleRepositoryServiceImpl.java index 75e6e4485b2c7f10f5bc2eaf99c13d450a408ed6..0b718a5e673201f90b187ac24e4a82b3bc5878db 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CycleRepositoryServiceImpl.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/impl/service/CycleRepositoryServiceImpl.java @@ -3,14 +3,10 @@ package org.activiti.cycle.impl.service; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; -import org.activiti.cycle.ArtifactType; import org.activiti.cycle.Content; -import org.activiti.cycle.MimeType; import org.activiti.cycle.RepositoryArtifact; import org.activiti.cycle.RepositoryArtifactLink; -import org.activiti.cycle.RepositoryArtifactType; import org.activiti.cycle.RepositoryConnector; import org.activiti.cycle.RepositoryException; import org.activiti.cycle.RepositoryFolder; @@ -18,19 +14,14 @@ import org.activiti.cycle.RepositoryNode; import org.activiti.cycle.RepositoryNodeCollection; import org.activiti.cycle.RepositoryNodeNotFoundException; import org.activiti.cycle.components.RuntimeConnectorList; -import org.activiti.cycle.context.CycleApplicationContext; import org.activiti.cycle.context.CycleSessionContext; import org.activiti.cycle.impl.RepositoryFolderImpl; import org.activiti.cycle.impl.RepositoryNodeCollectionImpl; -import org.activiti.cycle.impl.artifacttype.RepositoryArtifactTypes; import org.activiti.cycle.impl.conf.PasswordEnabledRepositoryConnectorConfiguration; import org.activiti.cycle.impl.connector.util.TransactionalConnectorUtils; import org.activiti.cycle.impl.db.CycleLinkDao; import org.activiti.cycle.impl.db.entity.RepositoryArtifactLinkEntity; -import org.activiti.cycle.impl.mimetype.Mimetypes; -import org.activiti.cycle.impl.transform.Transformations; import org.activiti.cycle.service.CycleRepositoryService; -import org.activiti.cycle.transform.ContentTransformationException; /** * @author bernd.ruecker@camunda.com diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/service/CyclePluginService.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/service/CyclePluginService.java index 201e3100df791b402cb8b9a0ef5b01fcc1043b1d..758d28d3f2532907369e6b6c0aee85f203bc8477 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/service/CyclePluginService.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/service/CyclePluginService.java @@ -1,8 +1,8 @@ package org.activiti.cycle.service; +import java.util.List; import java.util.Set; -import org.activiti.cycle.ContentProvider; import org.activiti.cycle.RepositoryArtifact; import org.activiti.cycle.RepositoryArtifactType; import org.activiti.cycle.action.Action; @@ -25,12 +25,12 @@ public interface CyclePluginService { public Set getDownloadContentActions(RepositoryArtifactType type); - public Set getParameterizedActions(RepositoryArtifact artifact); + public List getParameterizedActions(RepositoryArtifact artifact); - public Set getCreateUrlActions(RepositoryArtifact artifact); + public List getCreateUrlActions(RepositoryArtifact artifact); - public Set getDownloadContentActions(RepositoryArtifact artifact); + public List getDownloadContentActions(RepositoryArtifact artifact); - public Set getArtifactOpenLinkActions(RepositoryArtifact artifact); + public Set getArtifactOpenLinkActions(RepositoryArtifact artifact); } diff --git a/modules/activiti-cycle/src/main/java/org/activiti/cycle/service/CycleRepositoryService.java b/modules/activiti-cycle/src/main/java/org/activiti/cycle/service/CycleRepositoryService.java index 933c721bc930b0cfbd1066924ad3fcf860846362..b44d365f8a0a69f61f0b5229bfff938230e5d904 100644 --- a/modules/activiti-cycle/src/main/java/org/activiti/cycle/service/CycleRepositoryService.java +++ b/modules/activiti-cycle/src/main/java/org/activiti/cycle/service/CycleRepositoryService.java @@ -14,22 +14,14 @@ package org.activiti.cycle.service; import java.util.List; import java.util.Map; -import java.util.Set; -import org.activiti.cycle.ArtifactType; import org.activiti.cycle.Content; import org.activiti.cycle.ContentRepresentation; -import org.activiti.cycle.MimeType; import org.activiti.cycle.RepositoryArtifact; import org.activiti.cycle.RepositoryArtifactLink; -import org.activiti.cycle.RepositoryArtifactType; -import org.activiti.cycle.RepositoryConnector; import org.activiti.cycle.RepositoryFolder; import org.activiti.cycle.RepositoryNodeCollection; import org.activiti.cycle.RepositoryNodeNotFoundException; -import org.activiti.cycle.impl.artifacttype.RepositoryArtifactTypes; -import org.activiti.cycle.impl.mimetype.Mimetypes; -import org.activiti.cycle.transform.ContentTransformationException; /** * Cycle service used for accessing repositories.