1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.wcm.connector.fckeditor;
18
19 import java.io.OutputStreamWriter;
20 import java.net.URL;
21 import java.net.URLConnection;
22 import java.text.DateFormat;
23 import java.text.SimpleDateFormat;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.MissingResourceException;
29 import java.util.Random;
30 import java.util.ResourceBundle;
31
32 import javax.ws.rs.GET;
33 import javax.ws.rs.Path;
34 import javax.ws.rs.QueryParam;
35 import javax.ws.rs.core.CacheControl;
36 import javax.ws.rs.core.MediaType;
37 import javax.ws.rs.core.Response;
38 import javax.xml.parsers.DocumentBuilder;
39 import javax.xml.parsers.DocumentBuilderFactory;
40 import javax.xml.transform.dom.DOMSource;
41
42 import org.apache.commons.io.IOUtils;
43 import org.exoplatform.application.gadget.Gadget;
44 import org.exoplatform.application.gadget.GadgetRegistryService;
45 import org.exoplatform.application.registry.Application;
46 import org.exoplatform.application.registry.ApplicationCategory;
47 import org.exoplatform.application.registry.ApplicationRegistryService;
48 import org.exoplatform.container.PortalContainer;
49 import org.exoplatform.container.component.RequestLifeCycle;
50 import org.exoplatform.container.xml.InitParams;
51 import org.exoplatform.portal.config.model.ApplicationType;
52 import org.exoplatform.portal.gadget.core.ExoDefaultSecurityTokenGenerator;
53 import org.exoplatform.services.log.ExoLogger;
54 import org.exoplatform.services.log.Log;
55 import org.exoplatform.services.rest.resource.ResourceContainer;
56 import org.exoplatform.services.security.ConversationState;
57 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
58 import org.json.JSONObject;
59 import org.w3c.dom.Document;
60 import org.w3c.dom.Element;
61
62
63
64
65
66
67
68
69 @Path("/wcmGadget/")
70 public class GadgetConnector extends ExoDefaultSecurityTokenGenerator implements ResourceContainer {
71
72
73 public static final String FCK_RESOURCE_BUNDLE_FILE = "locale.services.fckeditor.FCKConnector";
74
75
76 private ApplicationRegistryService applicationRegistryService;
77
78
79 private GadgetRegistryService gadgetRegistryService;
80
81
82 private static final String LAST_MODIFIED_PROPERTY = "Last-Modified";
83
84
85 private static final String IF_MODIFIED_SINCE_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z";
86
87
88 private static final Log LOG = ExoLogger.getLogger(GadgetConnector.class.getName());
89
90
91
92
93
94
95 public GadgetConnector(InitParams initParams) throws Exception {
96 applicationRegistryService = WCMCoreUtils.getService(ApplicationRegistryService.class);
97 gadgetRegistryService = WCMCoreUtils.getService(GadgetRegistryService.class);
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111 @GET
112 @Path("/getFoldersAndFiles/")
113 public Response getFoldersAndFiles(@QueryParam("currentFolder") String currentFolder,
114 @QueryParam("lang") String lang,
115 @QueryParam("host") String host) throws Exception {
116 try {
117 Response response = buildXMLResponse(currentFolder, lang, host);
118 if (response != null)
119 return response;
120 } catch (Exception e) {
121 if (LOG.isErrorEnabled()) {
122 LOG.error("Error when perform getFoldersAndFiles: ", e);
123 }
124 }
125 DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
126 return Response.ok().header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date())).build();
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140 public Response buildXMLResponse(String currentFolder, String language, String host) throws Exception {
141 List<ApplicationCategory> applicationCategories = getGadgetCategories();
142 Element rootElement = createRootElement(currentFolder, applicationCategories, language, host);
143 Document document = rootElement.getOwnerDocument();
144 CacheControl cacheControl = new CacheControl();
145 cacheControl.setNoCache(true);
146 cacheControl.setNoStore(true);
147 DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
148 return Response.ok(new DOMSource(document), MediaType.TEXT_XML)
149 .cacheControl(cacheControl)
150 .header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date()))
151 .build();
152 }
153
154
155
156
157
158
159
160
161
162
163
164
165 private Element createRootElement(String currentFolder,
166 List<ApplicationCategory> applicationCategories,
167 String language,
168 String host) throws Exception {
169 Document document = null;
170 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
171 DocumentBuilder builder = factory.newDocumentBuilder();
172 document = builder.newDocument();
173 if (applicationCategories.isEmpty()) {
174 Locale locale = null;
175 if (language == null) {
176 locale = Locale.ENGLISH;
177 } else {
178 locale = new Locale(language);
179 }
180 ResourceBundle resourceBundle = ResourceBundle.getBundle(FCK_RESOURCE_BUNDLE_FILE, locale);
181 String message = "";
182 try {
183 message = resourceBundle.getString("fckeditor.no-gadget");
184 } catch (MissingResourceException e) {
185 message = "fckeditor.no-gadget";
186 }
187 Element rootElement = document.createElement("Message");
188 document.appendChild(rootElement);
189 rootElement.setAttribute("number", "555");
190 rootElement.setAttribute("text", message);
191 rootElement.setAttribute("type", "Error");
192 return rootElement;
193 }
194 Element rootElement = document.createElement("Connector");
195 document.appendChild(rootElement);
196 rootElement.setAttribute("resourceType", "Gadget");
197 Element currentFolderElement = document.createElement("CurrentFolder");
198 if (currentFolder == null || currentFolder.equals("/")){
199 currentFolderElement.setAttribute("name", applicationCategories.get(0).getName());
200 Element foldersElement = createFolderElement(document, applicationCategories);
201 rootElement.appendChild(foldersElement);
202 } else {
203 PortalContainer container = PortalContainer.getInstance();
204 RequestLifeCycle.begin(container);
205 try {
206 ApplicationCategory applicationCategory = applicationRegistryService
207 .getApplicationCategory(currentFolder.substring(1, currentFolder.length() - 1));
208 currentFolderElement.setAttribute("name", applicationCategory.getDisplayName());
209 Element filesElement = createFileElement(document, applicationCategory, host);
210 rootElement.appendChild(filesElement);
211 } finally {
212 RequestLifeCycle.end();
213 }
214 }
215 rootElement.appendChild(currentFolderElement);
216 return rootElement;
217 }
218
219
220
221
222
223
224
225
226
227
228
229 private Element createFolderElement(Document document,
230 List<ApplicationCategory> applicationCategories) throws Exception {
231 Element folders = document.createElement("Folders");
232 for (ApplicationCategory applicationCategory : applicationCategories) {
233 Element folder = document.createElement("Folder");
234 folder.setAttribute("name", applicationCategory.getDisplayName());
235 folders.appendChild(folder);
236 }
237 return folders;
238 }
239
240
241
242
243
244
245
246
247
248
249
250 private Element createFileElement(Document document,
251 ApplicationCategory applicationCategory,
252 String host) throws Exception {
253 Element files = document.createElement("Files");
254 List<Application> listApplication = applicationRegistryService.getApplications(applicationCategory,
255 ApplicationType.GADGET);
256 for (Application application : listApplication) {
257 Gadget gadget = gadgetRegistryService.getGadget(application.getApplicationName());
258 Element file = document.createElement("File");
259 file.setAttribute("name", gadget.getName());
260 file.setAttribute("fileType", "nt_unstructured");
261 file.setAttribute("size", "0");
262 file.setAttribute("thumbnail", gadget.getThumbnail());
263 file.setAttribute("description", gadget.getDescription());
264
265 String fullurl = "";
266 if (gadget.isLocal()) {
267 fullurl = "/" + PortalContainer.getCurrentRestContextName() + "/" + gadget.getUrl();
268 } else {
269 fullurl = gadget.getUrl();
270 }
271 file.setAttribute("url", fullurl);
272
273 String data = "{\"context\":{\"country\":\"US\",\"language\":\"en\"},\"gadgets\":[{\"moduleId\":0,\"url\":\""
274 + fullurl + "\",\"prefs\":[]}]}";
275 URL url = new URL(host + "/eXoGadgetServer/gadgets/metadata");
276 URLConnection conn = url.openConnection();
277 conn.setDoOutput(true);
278 OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
279 wr.write(data);
280 wr.flush();
281 String strMetadata = IOUtils.toString(conn.getInputStream(), "UTF-8");
282 wr.close();
283 JSONObject metadata = new JSONObject(strMetadata.toString());
284
285 ConversationState conversationState = ConversationState.getCurrent();
286 String userId = conversationState.getIdentity().getUserId();
287 String token = createToken(gadget.getUrl(), userId, userId, new Random().nextLong(), "default");
288 JSONObject obj = metadata.getJSONArray("gadgets").getJSONObject(0);
289 obj.put("secureToken", token);
290
291 file.setAttribute("metadata", metadata.toString());
292 files.appendChild(file);
293 }
294 return files;
295 }
296
297
298
299
300
301
302
303
304 private List<ApplicationCategory> getGadgetCategories() throws Exception {
305 List<ApplicationCategory> gadgetCategories = new ArrayList<ApplicationCategory>();
306 PortalContainer container = PortalContainer.getInstance();
307 RequestLifeCycle.begin(container);
308 try {
309 List<ApplicationCategory> applicationCategories = applicationRegistryService.getApplicationCategories();
310 for (ApplicationCategory applicationCategory : applicationCategories) {
311 if (!applicationRegistryService.getApplications(applicationCategory, ApplicationType.GADGET)
312 .isEmpty()) {
313 gadgetCategories.add(applicationCategory);
314 }
315 }
316 } finally {
317 RequestLifeCycle.end();
318 }
319 return gadgetCategories;
320 }
321 }