1 /*
2 * Copyright (C) 2003-2008 eXo Platform SAS.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Affero General Public License
6 * as published by the Free Software Foundation; either version 3
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see<http://www.gnu.org/licenses/>.
16 */
17 package org.exoplatform.services.ecm.publication;
18
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.util.HashMap;
22 import java.util.Locale;
23 import java.util.Map;
24
25 import javax.jcr.Node;
26
27 import org.exoplatform.container.component.BaseComponentPlugin;
28 import org.exoplatform.webui.core.UIComponent;
29 import org.exoplatform.webui.form.UIForm;
30
31 /**
32 * Base class of Publication plugins.
33 * Publication plugins implement a publication lifecycle. Each time a new
34 * custom lifecycle needs to be defined, a new plugin has to be implemented
35 * and registered with the Publication Service.
36 *
37 * The getName() method in the parent class is used to identify the lifecycle.
38 * The getDescription() method in the parent class is used to describe the
39 * lifecycle. Internationalization resource bundles are used in the
40 * implementation of the method.
41 */
42 public abstract class PublicationPlugin extends BaseComponentPlugin {
43
44 /**
45 * Retrieves all possible states in the publication lifecycle.
46 *
47 * @return an array of Strings giving the names of all possible states
48 */
49 public abstract String[] getPossibleStates();
50
51 /**
52 * Change the state of the specified Node.
53 * The implementation of this method basically retrieves the current
54 * state from the publication mixin of the specified Node. Then, based on
55 * the newState, it is able to determine if the update is possible. If
56 * yes, appropriate action is made (eg: launch a publication workflow). In
57 * all cases, the current state information is updated in the publication
58 * mixin of the specified Node.
59 *
60 * @param node the Node whose state needs to be changed
61 * @param newState the new state.
62 * @param context a Hashmap containing contextual information needed
63 * to change the state. The information set is defined on a State basis.
64 *
65 * @throws IncorrectStateUpdateLifecycleException if the update is not
66 * allowed
67 * @throws Exception the exception
68 */
69 public abstract void changeState(Node node,
70 String newState,
71 HashMap<String, String> context)
72 throws IncorrectStateUpdateLifecycleException, Exception;
73
74 /**
75 * Retrieves the WebUI form corresponding to the current state of the
76 * specified node.
77 * There are two cases here. Either the form contains read only fields (when
78 * the state is supposed to be processed by an external entity such as a
79 * Workflow). Or the form has editable fields or buttons (in the case the
80 * user can interfere. In that case, some action listeners are leveraged.).
81 * In all cases, all UI and listener classes are provided in the JAR
82 * corresponding to the PublicationPlugin.
83 * The method first inspects the specified Node. If it does not contain
84 * a publication mixin, then it throws a NotInPublicationLifecycleException
85 * exception. Else, it retrieves the lifecycle name from the mixin,
86 * selects the appropriate publication plugin and delegates the call to it.
87 *
88 * @param node the Node from which the state UI should be retrieved
89 * @param component the component
90 *
91 * @return a WebUI form corresponding to the current state and node.
92 *
93 * @throws Exception the exception
94 */
95 public abstract UIForm getStateUI(Node node, UIComponent component) throws Exception;
96
97 /**
98 * Retrieves an image showing the lifecycle state of the specified Node.
99 * The implementation of this method typically retrieves the current state
100 * of the specified Node, then fetches the bytes of an appropriate image
101 * found in the jar of the plugin. This image is supposed to be shown in
102 * the publication dialog of the JCR File Explorer Portlet.
103 *
104 * @param node the node from which the image should be obtained
105 * @param locale the locale
106 *
107 * @return an array of bytes corresponding to the image to be shown to the
108 * user
109 *
110 * @throws IOException Signals that an I/O exception has occurred.
111 * @throws FileNotFoundException the file not found exception
112 * @throws Exception the exception
113 */
114 public abstract byte[] getStateImage(Node node, Locale locale) throws IOException,FileNotFoundException,Exception;
115
116 /**
117 * Retrieves description information explaining to the user the current
118 * publication state of the specified Node. Possible examples are
119 * - "The document has been submitted to the following group for validation:
120 * /organization/management.".
121 * - "The document has been validated and will be published from
122 * May 3rd 10:00am to May 3rd 10:00pm. At that time, it will be unpublished
123 * and put in a backup state.".
124 * - "The document is in draft state. At any time you can turn it to
125 * published state."
126 *
127 * The returned message should be obtained from internationalization
128 * resource bundles (ie not hardcoded).
129 *
130 * @param node the node from which the publication state should be retrieved
131 * @param locale the locale
132 *
133 * @return a String giving the current state.
134 *
135 * @throws Exception the exception
136 */
137 public abstract String getUserInfo(Node node, Locale locale) throws Exception;
138
139 /**
140 * Retrieves the lifecycleName.
141 *
142 * @return a String giving the lifecycleName
143 */
144
145 public String getLifecycleName() {
146 return getName();
147 }
148
149 /**
150 * Retrieves the description of the plugin.
151 *
152 * @param node the node
153 *
154 * @return a String giving the description
155 */
156 public String getNodeLifecycleDesc(Node node) {
157 return getDescription();
158 }
159
160 /**
161 * Return if the plugin can add the specific mixin for the publication.
162 *
163 * @param node the node to add the mixin
164 *
165 * @return boolean
166 *
167 * @throws Exception the exception
168 */
169 public abstract boolean canAddMixin (Node node) throws Exception;
170
171 /**
172 * Add the specific plugin mixin to the node.
173 *
174 * @param node the node
175 *
176 * @throws Exception the exception
177 */
178 public abstract void addMixin (Node node) throws Exception;
179
180 /**
181 * Retrieves a node view of the specific node in a context
182 *
183 * @param node the node
184 * @param context the context
185 *
186 * @return the node to view
187 *
188 * @throws Exception the exception
189 */
190 public abstract Node getNodeView(Node node, Map<String,Object> context) throws Exception;
191
192 /**
193 * Get localized log messages and substitute variables.
194 *
195 * @param locale : the locale to use
196 * @param key : the key to translate
197 * @param values : array of string to susbtitute in the string
198 *
199 * @return a string localized and where values are substitute
200 */
201 public abstract String getLocalizedAndSubstituteMessage(Locale locale, String key, String[] values) throws Exception;
202 }