001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.automation;
020
021import java.io.Serializable;
022import java.util.Arrays;
023
024import org.nuxeo.common.xmap.annotation.XNode;
025import org.nuxeo.common.xmap.annotation.XNodeList;
026import org.nuxeo.common.xmap.annotation.XObject;
027import org.nuxeo.ecm.automation.core.Constants;
028import org.nuxeo.ecm.automation.core.OperationChainContribution;
029import org.nuxeo.ecm.platform.forms.layout.api.WidgetDefinition;
030
031/**
032 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
033 * @author <a href="mailto:grenard@nuxeo.com">Guillaume Renard</a>
034 */
035public class OperationDocumentation implements Comparable<OperationDocumentation>, Serializable {
036
037    private static final long serialVersionUID = 1L;
038
039    public String id;
040
041    /**
042     * @since 7.1
043     */
044    public String[] aliases;
045
046    /**
047     * an array of size multiple of 2. Each pair in the array is the input and output type of a method.
048     */
049    public String[] signature;
050
051    public String category;
052
053    public String label;
054
055    public String requires;
056
057    public String since;
058
059    /**
060     * @since 5.9.1
061     */
062    public String deprecatedSince;
063
064    /**
065     * @since 5.9.1
066     */
067    public boolean addToStudio;
068
069    /**
070     * @since 5.9.1
071     */
072    public String implementationClass;
073
074    public String description;
075
076    public Param[] params;
077
078    public WidgetDefinition[] widgetDefinitions;
079
080    /**
081     * The operations listing in case of a chain.
082     */
083    public OperationChainContribution.Operation[] operations;
084
085    // optional URL indicating the relative path (relative to the automation
086    // service home)
087    // of the page where the operation is exposed
088    public String url;
089
090    /**
091     * Returns a simple copy of an {@link OperationDocumentation} for an alias.
092     * <p>
093     * Array fields of {@code od} are shallow copied.
094     *
095     * @since 9.1
096     */
097    public static OperationDocumentation copyForAlias(OperationDocumentation od, String alias) {
098        OperationDocumentation documentation = new OperationDocumentation(alias);
099        documentation.signature = od.signature;
100        documentation.category = od.category;
101        documentation.label = od.label;
102        documentation.requires = od.requires;
103        documentation.since = od.since;
104        documentation.deprecatedSince = od.deprecatedSince;
105        documentation.addToStudio = od.addToStudio;
106        documentation.implementationClass = od.implementationClass;
107        documentation.description = od.description;
108        documentation.params = od.params;
109        documentation.widgetDefinitions = od.widgetDefinitions;
110        return documentation;
111    }
112
113    public OperationDocumentation(String id) {
114        this.id = id;
115        url = id;
116    }
117
118    @XObject("param")
119    public static class Param implements Serializable, Comparable<Param> {
120        private static final long serialVersionUID = 1L;
121
122        @XNode("@name")
123        public String name;
124
125        @XNode("@description")
126        public String description;
127
128        @XNode("@type")
129        public String type; // the data type
130
131        // is this useful (?)
132        public String widget; // the widget type
133
134        // is this useful (?)
135        @XNodeList(value = "value", type = String[].class, componentType = String.class)
136        public String[] values; // the default values
137
138        // is this useful (?)
139        @XNode("@order")
140        public int order;
141
142        // is this useful (?)
143        @XNode("@required")
144        public boolean required;
145
146        public Param() {
147        }
148
149        public String getName() {
150            return name;
151        }
152
153        /**
154         * @since 5.7.3
155         */
156        public String getDescription() {
157            return description;
158        }
159
160        public String getType() {
161            return type;
162        }
163
164        public String getWidget() {
165            return widget;
166        }
167
168        public String[] getValues() {
169            return values;
170        }
171
172        public boolean isRequired() {
173            return required;
174        }
175
176        public int getOrder() {
177            return order;
178        }
179
180        @Override
181        public String toString() {
182            return name + " [" + type + "] " + (required ? "required" : "optional");
183        }
184
185        @Override
186        public int compareTo(Param o) {
187            if (order != 0 && o.order != 0) {
188                if (order < o.order) {
189                    return -1;
190                } else if (order > o.order) {
191                    return 1;
192                }
193            }
194            if (required && !o.required) {
195                return -1;
196            }
197            if (o.required && !required) {
198                return 1;
199            }
200            return name.compareTo(o.name);
201        }
202    }
203
204    @Override
205    public int compareTo(OperationDocumentation o) {
206        String s1 = label == null ? id : label;
207        String s2 = o.label == null ? o.id : o.label;
208        return s1.compareTo(s2);
209    }
210
211    public String getDescription() {
212        return description;
213    }
214
215    /**
216     * @since 5.9.1
217     */
218    public String getSince() {
219        return since;
220    }
221
222    /**
223     * @since 5.9.1
224     */
225    public String getDeprecatedSince() {
226        return deprecatedSince;
227    }
228
229    /**
230     * @since 5.9.1
231     */
232    public boolean isAddToStudio() {
233        return addToStudio;
234    }
235
236    /**
237     * @since 5.9.1
238     */
239    public String getImplementationClass() {
240        return implementationClass;
241    }
242
243    /**
244     * @since 5.9.4
245     */
246    public boolean isChain() {
247        return (id != null && id.startsWith(Constants.CHAIN_ID_PREFIX)) || Constants.CAT_CHAIN.equals(category);
248    }
249
250    public String[] getSignature() {
251        return signature;
252    }
253
254    public String getCategory() {
255        return category;
256    }
257
258    public String getId() {
259        return id;
260    }
261
262    public String getUrl() {
263        return url;
264    }
265
266    public String getLabel() {
267        return label;
268    }
269
270    public String getRequires() {
271        return requires;
272    }
273
274    public Param[] getParams() {
275        return params;
276    }
277
278    public String[] getAliases() {
279        return aliases;
280    }
281
282    public void setAliases(String[] aliases) {
283        this.aliases = aliases;
284    }
285
286    public OperationChainContribution.Operation[] getOperations() {
287        return operations;
288    }
289
290    @Override
291    public String toString() {
292        return category + " > " + label + " [" + id + ": " + Arrays.asList(signature) + "] (" + params + ")\n"
293                + description;
294    }
295}