View Javadoc
1   /*
2    * Copyright (C) 2003-2009 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.ecm.webui.component.explorer.control.action;
18  
19  import java.security.AccessControlException;
20  import java.util.Arrays;
21  import java.util.List;
22  import java.util.regex.Matcher;
23  
24  import javax.jcr.AccessDeniedException;
25  import javax.jcr.ItemExistsException;
26  import javax.jcr.Node;
27  import javax.jcr.Session;
28  import javax.jcr.nodetype.ConstraintViolationException;
29  
30  import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer;
31  import org.exoplatform.ecm.webui.component.explorer.UIWorkingArea;
32  import org.exoplatform.ecm.webui.component.explorer.control.filter.CanAddNodeFilter;
33  import org.exoplatform.ecm.webui.component.explorer.control.filter.CanAddSymlinkFilter;
34  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsCheckedOutFilter;
35  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsLockForSymlink;
36  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotEditingDocumentFilter;
37  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotInTrashFilter;
38  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotSymlinkFilter;
39  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotTrashHomeNodeFilter;
40  import org.exoplatform.ecm.webui.component.explorer.control.listener.UIActionBarActionListener;
41  import org.exoplatform.ecm.webui.component.explorer.symlink.UISymLinkManager;
42  import org.exoplatform.ecm.webui.utils.Utils;
43  import org.exoplatform.services.cms.link.LinkManager;
44  import org.exoplatform.services.jcr.util.Text;
45  import org.exoplatform.services.log.ExoLogger;
46  import org.exoplatform.services.log.Log;
47  import org.exoplatform.web.application.ApplicationMessage;
48  import org.exoplatform.webui.config.annotation.ComponentConfig;
49  import org.exoplatform.webui.config.annotation.EventConfig;
50  import org.exoplatform.webui.core.UIApplication;
51  import org.exoplatform.webui.core.UIPopupContainer;
52  import org.exoplatform.webui.event.Event;
53  import org.exoplatform.webui.ext.filter.UIExtensionFilter;
54  import org.exoplatform.webui.ext.filter.UIExtensionFilters;
55  import org.exoplatform.webui.ext.manager.UIAbstractManager;
56  import org.exoplatform.webui.ext.manager.UIAbstractManagerComponent;
57  
58  /**
59   * Created by The eXo Platform SAS
60   * Author : eXoPlatform
61   *          nicolas.filotto@exoplatform.com
62   * 6 mai 2009
63   */
64  @ComponentConfig(
65       events = {
66         @EventConfig(listeners = AddSymLinkActionComponent.AddSymLinkActionListener.class)
67       }
68   )
69  
70  public class AddSymLinkActionComponent extends UIAbstractManagerComponent {
71  
72    private static final List<UIExtensionFilter> FILTERS =
73      Arrays.asList(new UIExtensionFilter[]{new CanAddNodeFilter(),
74                                            new CanAddSymlinkFilter(),
75                                            new IsLockForSymlink(),
76                                            new IsCheckedOutFilter(),
77                                            new IsNotSymlinkFilter(),
78                                            new IsNotTrashHomeNodeFilter(),
79                                            new IsNotInTrashFilter(),
80                                            new IsNotEditingDocumentFilter()});
81  
82    private static final Log LOG = ExoLogger.getLogger(AddSymLinkActionComponent.class.getName());
83  
84    @UIExtensionFilters
85    public List<UIExtensionFilter> getFilters() {
86      return FILTERS;
87    }
88  
89    public static class AddSymLinkActionListener extends UIActionBarActionListener<AddSymLinkActionComponent> {
90      public void processEvent(Event<AddSymLinkActionComponent> event) throws Exception {
91        UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
92        UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
93        String srcPath = event.getRequestContext().getRequestParameter(OBJECTID);
94        Node currentNode = uiExplorer.getCurrentNode();
95        UIApplication uiApp = event.getSource().getAncestorOfType(UIApplication.class);
96        LinkManager linkManager = uiWorkingArea.getApplicationComponent(LinkManager.class);
97        String symLinkName;
98        try {
99          if ((srcPath != null) && (srcPath.indexOf(";") > -1)) {
100 
101           String[] nodePaths = srcPath.split(";");
102           for (int i = 0; i < nodePaths.length; i++) {
103             Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(nodePaths[i]);
104             String wsName = null;
105             if (matcher.find()) {
106               wsName = matcher.group(1);
107               nodePaths[i] = matcher.group(2);
108             } else {
109               throw new IllegalArgumentException("The ObjectId is invalid '" + nodePaths[i] + "'");
110             }
111             Session userSession = uiExplorer.getSessionByWorkspace(wsName);
112             // Use the method getNodeByPath because it is link aware
113             Node selectedNode = uiExplorer.getNodeByPath(nodePaths[i], userSession, false);
114             // Reset the path to manage the links that potentially create
115             // virtual path
116             nodePaths[i] = selectedNode.getPath();
117             if (linkManager.isLink(selectedNode)) {
118               Object[] args = { selectedNode.getPath() };
119               uiApp.addMessage(new ApplicationMessage("UIWorkingArea.msg.selected-is-link", args,
120                   ApplicationMessage.WARNING));
121               
122               continue;
123             }
124             try {
125               if (selectedNode.getName().indexOf(".lnk") > -1)
126                 symLinkName = selectedNode.getName();
127               else
128                 symLinkName = selectedNode.getName() + ".lnk";
129               linkManager.createLink(currentNode, Utils.EXO_SYMLINK, selectedNode, symLinkName);
130             } catch (Exception e) {
131               Object[] arg = { Text.unescapeIllegalJcrChars(selectedNode.getPath()),
132                   Text.unescapeIllegalJcrChars(currentNode.getPath()) };
133               uiApp.addMessage(new ApplicationMessage("UIWorkingArea.msg.create-link-problem",
134                                                       arg,
135                                                       ApplicationMessage.WARNING));
136 
137               return;
138             }
139           }
140           uiExplorer.updateAjax(event);
141         } else {
142           if (srcPath != null) {
143             Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(srcPath);
144             String wsName = null;
145             if (matcher.find()) {
146               wsName = matcher.group(1);
147               srcPath = matcher.group(2);
148             } else {
149               throw new IllegalArgumentException("The ObjectId is invalid '" + srcPath + "'");
150             }
151             Session userSession = uiExplorer.getSessionByWorkspace(wsName);
152             // Use the method getNodeByPath because it is link aware
153             Node selectedNode = uiExplorer.getNodeByPath(srcPath, userSession, false);
154             // Reset the path to manage the links that potentially create
155             // virtual path
156             srcPath = selectedNode.getPath();
157             // Reset the session to manage the links that potentially change of
158             // workspace
159             userSession = selectedNode.getSession();
160             if (linkManager.isLink(selectedNode)) {
161               Object[] args = { selectedNode.getPath() };
162               uiApp.addMessage(new ApplicationMessage("UIWorkingArea.msg.selected-is-link", args,
163                   ApplicationMessage.WARNING));
164               
165               return;
166             }
167             if (selectedNode.getName().indexOf(".lnk") > -1)
168               symLinkName = selectedNode.getName();
169             else
170               symLinkName = selectedNode.getName() + ".lnk";
171             try {
172               linkManager.createLink(currentNode, Utils.EXO_SYMLINK, selectedNode, symLinkName);
173             } catch (Exception e) {
174               Object[] arg = { Text.unescapeIllegalJcrChars(selectedNode.getPath()),
175                   Text.unescapeIllegalJcrChars(currentNode.getPath()) };
176               uiApp.addMessage(new ApplicationMessage("UIWorkingArea.msg.create-link-problem",
177                                                       arg,
178                                                       ApplicationMessage.WARNING));
179 
180               return;
181             }
182             uiExplorer.updateAjax(event);
183           } else {
184         UIPopupContainer UIPopupContainer = uiExplorer.getChild(UIPopupContainer.class);
185         UISymLinkManager uiSymLinkManager = event.getSource().createUIComponent(UISymLinkManager.class, null, null);
186         uiSymLinkManager.useWorkspaceSelector();
187         UIPopupContainer.activate(uiSymLinkManager, 600, 190);
188         event.getRequestContext().addUIComponentToUpdateByAjax(UIPopupContainer);
189           }
190         }
191       } catch (AccessControlException ace) {
192         uiApp.addMessage(new ApplicationMessage("UISymLinkForm.msg.repository-exception", null,
193             ApplicationMessage.WARNING));
194         
195         return;
196       } catch (AccessDeniedException ade) {
197         uiApp.addMessage(new ApplicationMessage("UISymLinkForm.msg.repository-exception", null,
198             ApplicationMessage.WARNING));
199         
200         return;
201       } catch (NumberFormatException nume) {
202         uiApp.addMessage(new ApplicationMessage("UISymLinkForm.msg.numberformat-exception", null,
203             ApplicationMessage.WARNING));
204         
205         return;
206       } catch (ConstraintViolationException cve) {
207         uiApp.addMessage(new ApplicationMessage("UISymLinkForm.msg.cannot-save", null,
208             ApplicationMessage.WARNING));
209         
210         return;
211       } catch (ItemExistsException iee) {
212         uiApp.addMessage(new ApplicationMessage("UISymLinkForm.msg.item-exists-exception", null,
213             ApplicationMessage.WARNING));
214         
215         return;
216       } catch (Exception e) {
217         if (LOG.isErrorEnabled()) {
218           LOG.error("an unexpected error occurs while adding a symlink to the node", e);
219         }
220         uiApp.addMessage(new ApplicationMessage("UISymLinkForm.msg.cannot-save", null,
221             ApplicationMessage.WARNING));
222         
223         return;
224       }
225     }
226   }
227 
228   @Override
229   public Class<? extends UIAbstractManager> getUIAbstractManagerClass() {
230     return null;
231   }
232 }