View Javadoc

1   /**
2    * This file Copyright (c) 2012-2014 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.contentapp.movedialog.action;
35  
36  import info.magnolia.event.EventBus;
37  import info.magnolia.jcr.util.NodeUtil;
38  import info.magnolia.ui.api.action.ActionExecutionException;
39  import info.magnolia.ui.api.context.UiContext;
40  import info.magnolia.ui.api.event.AdmincentralEventBus;
41  import info.magnolia.ui.api.event.ContentChangedEvent;
42  import info.magnolia.ui.contentapp.movedialog.MoveActionCallback;
43  import info.magnolia.ui.framework.action.AbstractMultiItemAction;
44  import info.magnolia.ui.framework.action.MoveLocation;
45  import info.magnolia.ui.vaadin.integration.jcr.JcrItemAdapter;
46  import info.magnolia.ui.vaadin.integration.jcr.JcrItemUtil;
47  import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
48  
49  import java.util.List;
50  
51  import javax.inject.Named;
52  import javax.jcr.Node;
53  import javax.jcr.RepositoryException;
54  import javax.jcr.Session;
55  
56  import org.slf4j.Logger;
57  import org.slf4j.LoggerFactory;
58  
59  import com.vaadin.data.Item;
60  
61  /**
62   * Action that moves a node.
63   *
64   * @see MoveNodeActionDefinition
65   */
66  public class MoveNodeAction extends AbstractMultiItemAction<MoveNodeActionDefinition> {
67  
68      private final Logger log = LoggerFactory.getLogger(getClass());
69  
70      /**
71       * The item where the items should be moved relative to.
72       */
73      private final JcrNodeAdapter targetItem;
74  
75      protected final EventBus admincentralEventBus;
76  
77      private MoveActionCallback callback;
78  
79      private MoveLocation moveLocation = MoveLocation.BEFORE;
80  
81      public MoveNodeAction(
82              MoveNodeActionDefinition definition,
83              List<JcrItemAdapter> items,
84              JcrNodeAdapter targetItem,
85              @Named(AdmincentralEventBus.NAME) EventBus admincentralEventBus,
86              UiContext uiContext,
87              MoveActionCallback callback) {
88          super(definition, items, uiContext);
89          this.targetItem = targetItem;
90          this.admincentralEventBus = admincentralEventBus;
91          this.callback = callback;
92      }
93  
94      @Override
95      public void execute() throws ActionExecutionException {
96          super.execute();
97          Item firstItem = getItems().get(0);
98          if (firstItem instanceof JcrNodeAdapter) {
99              JcrNodeAdapter nodeAdapter = (JcrNodeAdapter) firstItem;
100             String itemIdOfChangedItem;
101             try {
102                 itemIdOfChangedItem = JcrItemUtil.getItemId(nodeAdapter.getJcrItem());
103                 admincentralEventBus.fireEvent(new ContentChangedEvent(nodeAdapter.getWorkspace(), itemIdOfChangedItem));
104                 callback.onMovePerformed(targetItem, moveLocation);
105             } catch (RepositoryException e) {
106                 callback.onMoveCancelled();
107             }
108         }
109     }
110 
111     @Override
112     protected void executeOnItem(JcrItemAdapter item) throws Exception {
113         if (basicMoveCheck(item.getJcrItem(), targetItem.getJcrItem())) {
114             moveLocation = getDefinition().getMoveLocation();
115 
116             Node source = (Node) item.getJcrItem();
117             Node target = targetItem.getJcrItem();
118 
119             switch (moveLocation) {
120                 case INSIDE:
121                     NodeUtil.moveNode(source, target);
122                     break;
123                 case BEFORE:
124                     NodeUtil.moveNodeBefore(source, target);
125                     break;
126                 case AFTER:
127                     NodeUtil.moveNodeAfter(source, target);
128                     break;
129             }
130             Session session = source.getSession();
131             session.save();
132         } else {
133             callback.onMoveCancelled();
134             throw new IllegalArgumentException("Move operation was not completed due to failed move validation.");
135         }
136     }
137 
138     @Override
139     protected String getSuccessMessage() {
140         return getDefinition().getSuccessMessage();
141     }
142 
143     @Override
144     protected String getFailureMessage() {
145         return getDefinition().getFailureMessage();
146     }
147 
148     /**
149      * Perform basic check.
150      */
151     private boolean basicMoveCheck(javax.jcr.Item source, javax.jcr.Item target) throws RepositoryException {
152         if (!target.isNode() || !source.isNode()) {
153             return false;
154         }
155         if (target.getPath().equals(source.getPath())) {
156             return false;
157         }
158         return !NodeUtil.isSame((Node) target, source.getParent());
159     }
160 }