View Javadoc
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.wcm.connector;
18  
19  import java.text.DateFormat;
20  import java.text.SimpleDateFormat;
21  import java.util.ArrayList;
22  import java.util.Date;
23  import java.util.List;
24  
25  import javax.jcr.Node;
26  import javax.jcr.NodeIterator;
27  import javax.jcr.Session;
28  import javax.ws.rs.core.CacheControl;
29  import javax.ws.rs.core.MediaType;
30  import javax.ws.rs.core.Response;
31  import javax.xml.transform.dom.DOMSource;
32  
33  import org.exoplatform.container.ExoContainer;
34  import org.exoplatform.container.ExoContainerContext;
35  import org.exoplatform.ecm.connector.fckeditor.FCKFileHandler;
36  import org.exoplatform.ecm.connector.fckeditor.FCKFolderHandler;
37  import org.exoplatform.ecm.connector.fckeditor.FCKUtils;
38  import org.exoplatform.services.cms.link.LinkManager;
39  import org.exoplatform.services.cms.voting.VotingService;
40  import org.exoplatform.services.jcr.RepositoryService;
41  import org.exoplatform.services.jcr.core.ManageableRepository;
42  import org.exoplatform.services.jcr.ext.common.SessionProvider;
43  import org.exoplatform.services.log.ExoLogger;
44  import org.exoplatform.services.log.Log;
45  import org.exoplatform.services.wcm.core.WebSchemaConfigService;
46  import org.exoplatform.services.wcm.portal.LivePortalManagerService;
47  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
48  import org.w3c.dom.Document;
49  import org.w3c.dom.Element;
50  
51  /*
52   * Created by The eXo Platform SAS Author : Anh Do Ngoc anh.do@exoplatform.com
53   * Sep 10, 2008
54   */
55  /**
56   * The Class BaseConnector.
57   */
58  public abstract class BaseConnector {
59  
60    /** The folder handler. */
61    protected FCKFolderHandler                  folderHandler;
62  
63    /** The file handler. */
64    protected FCKFileHandler                    fileHandler;
65  
66    /** The file upload handler. */
67    protected FileUploadHandler                 fileUploadHandler;
68  
69    /** The repository service. */
70    protected RepositoryService                 repositoryService;
71  
72    /** The log. */
73    private static final Log LOG = ExoLogger.getLogger(BaseConnector.class.getName());
74  
75    /** The voting service. */
76    protected VotingService votingService;
77  
78    /** The link manager. */
79    protected LinkManager linkManager;
80  
81    /** The live portal manager service. */
82    protected LivePortalManagerService          livePortalManagerService;
83  
84    /** The web schema config service. */
85    protected WebSchemaConfigService            webSchemaConfigService;
86  
87    /** The Constant LAST_MODIFIED_PROPERTY. */
88    protected static final String LAST_MODIFIED_PROPERTY = "Last-Modified";
89  
90    /** The Constant IF_MODIFIED_SINCE_DATE_FORMAT. */
91    protected static final String IF_MODIFIED_SINCE_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z";
92  
93    /**
94     * Gets the root content storage.
95     *
96     * @param node the node
97     * @return the root content storage
98     * @throws Exception the exception
99     */
100   protected abstract Node getRootContentStorage(Node node) throws Exception;
101 
102   /**
103    * Gets the content storage type.
104    *
105    * @return the content storage type
106    * @throws Exception the exception
107    */
108   protected abstract String getContentStorageType() throws Exception;
109 
110   /**
111    * Instantiates a new base connector.
112    */
113   public BaseConnector() {
114     livePortalManagerService = WCMCoreUtils.getService(LivePortalManagerService.class);
115     repositoryService = WCMCoreUtils.getService(RepositoryService.class);
116     webSchemaConfigService = WCMCoreUtils.getService(WebSchemaConfigService.class);
117     votingService = WCMCoreUtils.getService(VotingService.class);
118     linkManager = WCMCoreUtils.getService(LinkManager.class);
119 
120     ExoContainer container = ExoContainerContext.getCurrentContainer();
121     folderHandler = new FCKFolderHandler(container);
122     fileHandler = new FCKFileHandler(container);
123     fileUploadHandler = new FileUploadHandler();
124   }
125 
126   /**
127    * Builds the xml response on expand.
128    *
129    * @param currentFolder the current folder
130    * @param runningPortal The current portal instance
131    * @param workspaceName the workspace name
132    * @param jcrPath the jcr path
133    * @param command the command
134    * @return the response
135    * @throws Exception the exception
136    */
137   protected Response buildXMLResponseOnExpand(String currentFolder,
138                                               String runningPortal,
139                                               String workspaceName,
140                                               String jcrPath,
141                                               String command) throws Exception {
142     SessionProvider sessionProvider = WCMCoreUtils.getSystemSessionProvider();
143     Node sharedPortalNode = livePortalManagerService.getLiveSharedPortal(sessionProvider);
144     Node activePortalNode = getCurrentPortalNode(jcrPath,
145                                                  runningPortal,
146                                                  sharedPortalNode);
147     if (currentFolder.length() == 0 || "/".equals(currentFolder))
148       return buildXMLResponseForRoot(activePortalNode, sharedPortalNode, command);
149     String currentPortalRelPath = "/" + activePortalNode.getName() + "/";
150     String sharePortalRelPath = "/" + sharedPortalNode.getName() + "/";
151     Node webContent = getWebContent(workspaceName, jcrPath);
152     if (!activePortalNode.getPath().equals(sharedPortalNode.getPath())
153         && currentFolder.startsWith(sharePortalRelPath)) {
154       if (currentFolder.equals(sharePortalRelPath)) {
155         return buildXMLResponseForPortal(sharedPortalNode, null, command);
156       }
157       Node currentContentStorageNode = getCorrectContentStorage(sharedPortalNode,
158           null,
159           currentFolder);
160       return buildXMLResponseForContentStorage(currentContentStorageNode, command);
161     } else if (!activePortalNode.getPath().equals(sharedPortalNode.getPath())
162         && currentFolder.startsWith(currentPortalRelPath)) {
163       return buildXMLResponseCommon(activePortalNode, webContent, currentFolder, command);
164     } else {
165       return buildXMLResponseCommon(sharedPortalNode, webContent, currentFolder, command);
166     }
167   }
168 
169   /**
170    * Builds the xml response common.
171    *
172    * @param activePortal the active portal
173    * @param webContent the web content
174    * @param currentFolder the current folder
175    * @param command the command
176    * @return the response
177    * @throws Exception the exception
178    */
179   protected Response buildXMLResponseCommon(Node activePortal,
180                                             Node webContent,
181                                             String currentFolder,
182                                             String command) throws Exception {
183     String activePortalRelPath = "/" + activePortal.getName() + "/";
184     if (currentFolder.equals(activePortalRelPath))
185       return buildXMLResponseForPortal(activePortal, webContent, command);
186     if (webContent != null) {
187       String webContentRelPath = activePortalRelPath + webContent.getName() + "/";
188       if (currentFolder.startsWith(webContentRelPath)) {
189         if (currentFolder.equals(webContentRelPath))
190           return buildXMLResponseForPortal(webContent, null, command);
191         Node contentStorageOfWebContent = getCorrectContentStorage(activePortal,
192                                                                    webContent,
193                                                                    currentFolder);
194         return buildXMLResponseForContentStorage(contentStorageOfWebContent, command);
195       }
196     }
197     Node correctContentStorage = getCorrectContentStorage(activePortal, null, currentFolder);
198     return buildXMLResponseForContentStorage(correctContentStorage, command);
199   }
200 
201   /**
202    * Builds the xml response for root.
203    *
204    * @param currentPortal the current portal
205    * @param sharedPortal the shared portal
206    * @param command the command
207    * @return the response
208    * @throws Exception the exception
209    */
210   protected Response buildXMLResponseForRoot(Node currentPortal, Node sharedPortal, String command) throws Exception {
211     Document document = null;
212     Node rootNode = currentPortal.getSession().getRootNode();
213     Element rootElement = FCKUtils.createRootElement(command,
214                                                      rootNode,
215                                                      rootNode.getPrimaryNodeType().getName());
216     document = rootElement.getOwnerDocument();
217     Element folders = document.createElement("Folders");
218     Element files = document.createElement("Files");
219     Element sharedPortalElement = null;
220     Element currentPortalElement = null;
221     if (sharedPortal != null) {
222       sharedPortalElement = folderHandler.createFolderElement(document,
223                                                               sharedPortal,
224                                                               sharedPortal.getPrimaryNodeType()
225                                                                           .getName());
226       folders.appendChild(sharedPortalElement);
227     }
228     if (currentPortal != null && !currentPortal.getPath().equals(sharedPortal.getPath())) {
229       currentPortalElement = folderHandler.createFolderElement(document,
230                                                                currentPortal,
231                                                                currentPortal.getPrimaryNodeType()
232                                                                             .getName());
233       folders.appendChild(currentPortalElement);
234     }
235     rootElement.appendChild(folders);
236     rootElement.appendChild(files);
237     return getResponse(document);
238   }
239 
240   /**
241    * Builds the xml response for portal.
242    *
243    * @param node the node
244    * @param webContent the web content
245    * @param command the command
246    * @return the response
247    * @throws Exception the exception
248    */
249   protected Response buildXMLResponseForPortal(Node node, Node webContent, String command) throws Exception {
250     Node storageNode = getRootContentStorage(node);
251     Element rootElement = FCKUtils.createRootElement(command,
252                                                      node,
253                                                      folderHandler.getFolderType(node));
254     Document document = rootElement.getOwnerDocument();
255     Element folders = document.createElement("Folders");
256     Element files = document.createElement("Files");
257     Element storageElement = folderHandler.createFolderElement(document,
258                                                                storageNode,
259                                                                storageNode.getPrimaryNodeType()
260                                                                           .getName());
261     folders.appendChild(storageElement);
262     Element webContentElement = null;
263     if (webContent != null) {
264       webContentElement = folderHandler.createFolderElement(document,
265                                                             webContent,
266                                                             webContent.getPrimaryNodeType()
267                                                                       .getName());
268       folders.appendChild(webContentElement);
269     }
270     rootElement.appendChild(folders);
271     rootElement.appendChild(files);
272     return getResponse(document);
273   }
274 
275   /**
276    * Builds the xml response for content storage.
277    *
278    * @param node the node
279    * @param command the command
280    * @return the response
281    * @throws Exception the exception
282    */
283   protected Response buildXMLResponseForContentStorage(Node node, String command) throws Exception {
284     Element rootElement = FCKUtils.createRootElement(command,
285                                                      node,
286                                                      folderHandler.getFolderType(node));
287     Document document = rootElement.getOwnerDocument();
288     Element folders = document.createElement("Foders");
289     Element files = document.createElement("Files");
290     for (NodeIterator iterator = node.getNodes(); iterator.hasNext();) {
291       Node child = iterator.nextNode();
292       if (child.isNodeType(FCKUtils.EXO_HIDDENABLE))
293         continue;
294       String folderType = folderHandler.getFolderType(child);
295       if (folderType != null) {
296         Element folder = folderHandler.createFolderElement(document, child, folderType);
297         folders.appendChild(folder);
298       }
299       String sourceType = getContentStorageType();
300       String fileType = fileHandler.getFileType(child, sourceType);
301       if (fileType != null) {
302         Element file = fileHandler.createFileElement(document, child, fileType);
303         files.appendChild(file);
304       }
305     }
306     rootElement.appendChild(folders);
307     rootElement.appendChild(files);
308     return getResponse(document);
309   }
310 
311   protected Node getCorrectContentStorage(Node activePortal, Node webContent, String currentFolder) throws Exception {
312     if (currentFolder == null || currentFolder.trim().length() == 0)
313       return null;
314     Node rootContentStorage = null;
315     String rootContentStorageRelPath = null;
316     if (activePortal != null && webContent == null) {
317       rootContentStorage = getRootContentStorage(activePortal);
318       rootContentStorageRelPath = "/" + activePortal.getName() + "/" + rootContentStorage.getName()
319           + "/";
320     } else if (activePortal != null && webContent != null) {
321       rootContentStorage = getRootContentStorage(webContent);
322       rootContentStorageRelPath = "/" + activePortal.getName() + "/" + webContent.getName() + "/"
323           + rootContentStorage.getName() + "/";
324     }
325     if (currentFolder.equals(rootContentStorageRelPath))
326       return rootContentStorage;
327     try {
328       String correctStorageRelPath = currentFolder.replace(rootContentStorageRelPath, "");
329       correctStorageRelPath = correctStorageRelPath.substring(0, correctStorageRelPath.length() - 1);
330       return rootContentStorage.getNode(correctStorageRelPath);
331     } catch (Exception e) {
332       return null;
333     }
334   }
335 
336   /**
337    * Gets the response.
338    *
339    * @param document the document
340    * @return the response
341    */
342   protected Response getResponse(Document document) {
343     CacheControl cacheControl = new CacheControl();
344     cacheControl.setNoCache(true);
345     cacheControl.setNoStore(true);
346     DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
347     return Response.ok(new DOMSource(document), MediaType.TEXT_XML)
348                    .cacheControl(cacheControl)
349                    .header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date()))
350                    .build();
351   }
352 
353   /**
354    * Gets the jcr content.
355    *
356    * @param workspaceName the workspace name
357    * @param jcrPath the jcr path
358    * @return the jcr content
359    * @throws Exception the exception
360    */
361   protected Node getContent(String workspaceName,
362                             String jcrPath,
363                             String NodeTypeFilter,
364                             boolean isSystemSession) throws Exception {
365     if (jcrPath == null || jcrPath.trim().length() == 0)
366       return null;
367     try {
368       SessionProvider sessionProvider = isSystemSession ? WCMCoreUtils.getSystemSessionProvider()
369                                                        : WCMCoreUtils.getUserSessionProvider();
370       ManageableRepository repository = repositoryService.getCurrentRepository();
371       Session session = sessionProvider.getSession(workspaceName, repository);
372       Node content = (Node) session.getItem(jcrPath);
373       if (content.isNodeType("exo:taxonomyLink")) {
374         content = linkManager.getTarget(content);
375       }
376 
377       if (NodeTypeFilter==null || (NodeTypeFilter!=null && content.isNodeType(NodeTypeFilter)) )
378         return content;
379     } catch (Exception e) {
380       if (LOG.isErrorEnabled()) {
381         LOG.error("Error when perform getContent: ", e);
382       }
383     }
384     return null;
385   }
386   
387   /**
388    * Gets the jcr content.
389    *
390    * @param workspaceName the workspace name
391    * @param jcrPath the jcr path
392    * @return the jcr content
393    * @throws Exception the exception
394    */
395   protected Node getContent(String workspaceName, String jcrPath) throws Exception {
396     return getContent(workspaceName, jcrPath, null, true);
397   }  
398 
399   /**
400    * Gets the web content.
401    *
402    * @param workspaceName the workspace name
403    * @param jcrPath the jcr path
404    * @return the web content
405    * @throws Exception the exception
406    */
407   protected Node getWebContent(String workspaceName, String jcrPath) throws Exception {
408     return getContent(workspaceName, jcrPath, "exo:webContent", true);
409   }
410 
411   protected Node getCurrentPortalNode(String jcrPath,
412                                       String runningPortal,
413                                       Node sharedPortal) throws Exception {
414     if (jcrPath == null || jcrPath.length() == 0)
415       return null;
416     Node currentPortal = null;
417     List<Node> livePortaNodes = new ArrayList<Node>();
418     SessionProvider sessionProvider = WCMCoreUtils.getSystemSessionProvider();
419     try {
420       livePortaNodes = livePortalManagerService.getLivePortals(sessionProvider);
421       if (sharedPortal != null)
422         livePortaNodes.add(sharedPortal);
423       for (Node portalNode : livePortaNodes) {
424         String portalPath = portalNode.getPath();
425         if (jcrPath.startsWith(portalPath))
426           currentPortal = portalNode;
427       }
428       if (currentPortal == null)
429         currentPortal = livePortalManagerService.getLivePortal(sessionProvider, runningPortal);
430       return currentPortal;
431     } catch (Exception e) {
432       return null;
433     }
434   }
435 
436 }