View Javadoc
1   /**
2    * This file Copyright (c) 2013-2018 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.jcr.wrapper;
35  
36  import info.magnolia.jcr.decoration.ContentDecoratorNodeWrapper;
37  import info.magnolia.jcr.util.NodeTypes;
38  import info.magnolia.repository.RepositoryConstants;
39  
40  import java.io.InputStream;
41  import java.math.BigDecimal;
42  import java.util.ArrayList;
43  import java.util.Calendar;
44  import java.util.List;
45  
46  import javax.jcr.AccessDeniedException;
47  import javax.jcr.Binary;
48  import javax.jcr.InvalidItemStateException;
49  import javax.jcr.ItemExistsException;
50  import javax.jcr.ItemNotFoundException;
51  import javax.jcr.Node;
52  import javax.jcr.PathNotFoundException;
53  import javax.jcr.Property;
54  import javax.jcr.ReferentialIntegrityException;
55  import javax.jcr.RepositoryException;
56  import javax.jcr.UnsupportedRepositoryOperationException;
57  import javax.jcr.Value;
58  import javax.jcr.ValueFormatException;
59  import javax.jcr.lock.LockException;
60  import javax.jcr.nodetype.ConstraintViolationException;
61  import javax.jcr.nodetype.NoSuchNodeTypeException;
62  import javax.jcr.version.Version;
63  import javax.jcr.version.VersionException;
64  
65  import org.apache.commons.lang3.StringUtils;
66  import org.slf4j.Logger;
67  import org.slf4j.LoggerFactory;
68  
69  /**
70   * Wrapper to handle all required content modifications.
71   */
72  public class MgnlPropertySettingNodeWrapper extends ContentDecoratorNodeWrapper<MgnlPropertySettingContentDecorator> {
73  
74      private static Logger log = LoggerFactory.getLogger(MgnlPropertySettingNodeWrapper.class);
75  
76      private List<String> saveOnSave = new ArrayList<String>();
77  
78      public MgnlPropertySettingNodeWrapper(Node node, MgnlPropertySettingContentDecorator decorator) {
79          super(node, decorator);
80      }
81  
82      @Override
83      public Property setProperty(String name, BigDecimal value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
84          final Property prop = super.setProperty(name, value);
85          this.updateLastModifiedProperty(name);
86          return prop;
87      }
88  
89      @Override
90      public void setPrimaryType(String nodeTypeName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
91          super.setPrimaryType(nodeTypeName);
92          this.updateLastModified();
93      }
94  
95      @Override
96      public Property setProperty(String name, Binary value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
97          final Property prop = super.setProperty(name, value);
98          this.updateLastModifiedProperty(name);
99          return prop;
100     }
101 
102     @Override
103     public Property setProperty(String name, boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
104         final Property prop = super.setProperty(name, value);
105         this.updateLastModifiedProperty(name);
106         return prop;
107     }
108 
109     @Override
110     public Property setProperty(String name, Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
111         final Property prop = super.setProperty(name, value);
112         this.updateLastModifiedProperty(name);
113         return prop;
114     }
115 
116     @Override
117     public Property setProperty(String name, double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
118         final Property prop = super.setProperty(name, value);
119         this.updateLastModifiedProperty(name);
120         return prop;
121     }
122 
123     @Override
124     public Property setProperty(String name, InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
125         final Property prop = super.setProperty(name, value);
126         this.updateLastModifiedProperty(name);
127         return prop;
128     }
129 
130     @Override
131     public Property setProperty(String name, long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
132         final Property prop = super.setProperty(name, value);
133         this.updateLastModifiedProperty(name);
134         return prop;
135     }
136 
137     @Override
138     public Property setProperty(String name, Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
139         final Property prop = super.setProperty(name, value);
140         this.updateLastModifiedProperty(name);
141         return prop;
142     }
143 
144     @Override
145     public Property setProperty(String name, String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
146         final Property prop = super.setProperty(name, value);
147         this.updateLastModifiedProperty(name);
148         return prop;
149     }
150 
151     @Override
152     public Property setProperty(String name, String value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
153         final Property prop = super.setProperty(name, value, type);
154         this.updateLastModifiedProperty(name);
155         return prop;
156     }
157 
158     @Override
159     public Property setProperty(String name, String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
160         final Property prop = super.setProperty(name, values);
161         this.updateLastModifiedProperty(name);
162         return prop;
163     }
164 
165     @Override
166     public Property setProperty(String name, String[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
167         final Property prop = super.setProperty(name, values, type);
168         this.updateLastModifiedProperty(name);
169         return prop;
170     }
171 
172     @Override
173     public Property setProperty(String name, Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
174         final Property prop = super.setProperty(name, value);
175         this.updateLastModifiedProperty(name);
176         return prop;
177     }
178 
179     @Override
180     public Property setProperty(String name, Value value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
181         final Property prop = super.setProperty(name, value, type);
182         this.updateLastModifiedProperty(name);
183         return prop;
184     }
185 
186     @Override
187     public Property setProperty(String name, Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
188         final Property prop = super.setProperty(name, values);
189         this.updateLastModifiedProperty(name);
190         return prop;
191     }
192 
193     @Override
194     public Property setProperty(String name, Value[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
195         final Property prop = super.setProperty(name, values, type);
196         this.updateLastModifiedProperty(name);
197         return prop;
198     }
199 
200     @Override
201     public Node addNode(String relPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException {
202         Node node = super.addNode(relPath);
203         this.updateLastModified();
204         setCreatedProperty(node.getPath());
205         return node;
206     }
207 
208     @Override
209     public Node addNode(String relPath, String primaryNodeTypeName) throws ItemExistsException, PathNotFoundException, NoSuchNodeTypeException, LockException, VersionException, ConstraintViolationException, RepositoryException {
210         Node node = super.addNode(relPath, primaryNodeTypeName);
211         if (RepositoryConstants.WEBSITE.equals(this.getSession().getWorkspace().getName()) && NodeTypes.Page.NAME.equals(primaryNodeTypeName)) {
212             // no LUD update on adding subpages
213         } else {
214             this.updateLastModified();
215         }
216         setCreatedProperty(node.getPath());
217         return node;
218     }
219 
220     @Override
221     public void orderBefore(String srcChildRelPath, String destChildRelPath) throws UnsupportedRepositoryOperationException, VersionException, ConstraintViolationException, ItemNotFoundException, LockException, RepositoryException {
222         super.orderBefore(srcChildRelPath, destChildRelPath);
223         String path = StringUtils.removeEnd(this.getPath(), "/") + "/" + srcChildRelPath;
224         // yes, we have moved parent page around so it is ordered differently in relation to its siblings, however there is no change from child page of view
225         updateLastModified(path, false);
226         this.saveOnSave.add(srcChildRelPath);
227     }
228 
229     @Override
230     public void doneMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
231         super.doneMerge(version);
232         this.updateLastModified();
233     }
234 
235     @Override
236     public void remove() throws VersionException, LockException, ConstraintViolationException, AccessDeniedException, RepositoryException {
237         Node parent = this.getParent();
238         super.remove();
239         String workspaceName = this.getSession().getWorkspace().getName();
240         // as insane as it might look we might need to update lud on parent in case this is the component in a page, but not otherwise! (except maybe for data)
241         if (RepositoryConstants.WEBSITE.equals(workspaceName)) {
242             getContentDecorator().updateLastModified(workspaceName, parent.getPath());
243         }
244     }
245 
246     @Override
247     public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
248         super.save();
249         // we modified status of child node. This is not necessary when session.save() is called instead of node.save()
250         for (String child : saveOnSave) {
251             log.debug("forcing on child: {}::{}", this.getSession().toString(), child);
252             this.getNode(child).save();
253         }
254         saveOnSave.clear();
255     }
256 
257     private void updateLastModified() throws PathNotFoundException, RepositoryException {
258         if (this.isNew()) {
259             // node itself is not saved, nothing to do
260             return;
261         }
262         getContentDecorator().updateLastModified(this.getSession().getWorkspace().getName(), this.getPath());
263     }
264 
265     private void updateLastModified(String path, boolean recursiveDown) throws PathNotFoundException, RepositoryException {
266         if (this.isNew()) {
267             // node itself is not saved, nothing to do
268             return;
269         }
270         getContentDecorator().updateLastModified(this.getSession().getWorkspace().getName(), path, recursiveDown);
271     }
272 
273     private void updateLastModifiedProperty(String name) throws PathNotFoundException, RepositoryException {
274         if (this.isNew()) {
275             // node itself is not saved, nothing to do
276             return;
277         }
278         getContentDecorator().updateLastModifiedProperty(this.getSession().getWorkspace().getName(), name, this.getPath());
279     }
280 
281     private void setCreatedProperty(final String path) throws RepositoryException {
282         getContentDecorator().setCreatedDate(this.getSession().getWorkspace().getName(), path);
283     }
284 }