View Javadoc
1   /**
2    * This file Copyright (c) 2013-2015 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.audit;
35  
36  import info.magnolia.jcr.decoration.ContentDecoratorNodeWrapper;
37  import info.magnolia.jcr.util.NodeTypes;
38  
39  import java.io.InputStream;
40  import java.math.BigDecimal;
41  import java.util.Calendar;
42  import java.util.LinkedHashMap;
43  import java.util.LinkedList;
44  import java.util.Map;
45  import java.util.Map.Entry;
46  
47  import javax.jcr.AccessDeniedException;
48  import javax.jcr.Binary;
49  import javax.jcr.InvalidItemStateException;
50  import javax.jcr.ItemExistsException;
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.Value;
57  import javax.jcr.ValueFormatException;
58  import javax.jcr.lock.LockException;
59  import javax.jcr.nodetype.ConstraintViolationException;
60  import javax.jcr.nodetype.NoSuchNodeTypeException;
61  import javax.jcr.nodetype.NodeType;
62  import javax.jcr.version.VersionException;
63  
64  /**
65   * A Node wrapper implementation which inform
66   * Magnolia audit logging content decorator {@link info.magnolia.audit.MgnlAuditLoggingContentDecorator} about action (Create, Modify, Delete) on the node.
67   * The implementation also take care about logging appropriate actions into audit-log output during save action of node.
68   */
69  public class MgnlAuditLoggingContentDecoratorNodeWrapper extends ContentDecoratorNodeWrapper<MgnlAuditLoggingContentDecorator> {
70  
71      public MgnlAuditLoggingContentDecoratorNodeWrapper(Node node, MgnlAuditLoggingContentDecorator contentDecorator) {
72          super(node, contentDecorator);
73      }
74  
75      @Override
76      public Node addNode(String relPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException {
77          Node node = super.addNode(relPath);
78          getContentDecorator().logActionCreate(node);
79          return node;
80      }
81  
82      @Override
83      public Node addNode(String relPath, String primaryNodeTypeName) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException {
84          Node node = super.addNode(relPath, primaryNodeTypeName);
85          getContentDecorator().logActionCreate(node);
86          return node;
87      }
88  
89      @Override
90      public void remove() throws VersionException, LockException, ConstraintViolationException, AccessDeniedException, RepositoryException {
91          final NodeType nodeType = getPrimaryNodeType();
92          final String path = getPath();
93          final String workspace = getSession().getWorkspace().getName();
94          super.remove();
95          getContentDecorator().logActionDelete(path, workspace, nodeType);
96  
97      }
98  
99      @Override
100     public void addMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
101         super.addMixin(mixinName);
102         getContentDecorator().logActionModify(this);
103     }
104 
105     @Override
106     public void removeMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
107         super.removeMixin(mixinName);
108         getContentDecorator().logActionModify(this);
109     }
110 
111     @Override
112     public void setPrimaryType(String nodeTypeName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
113         super.setPrimaryType(nodeTypeName);
114         getContentDecorator().logActionModify(this);
115     }
116 
117     @Override
118     public Property setProperty(String name, Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
119         Property property = super.setProperty(name, value);
120         logActionModify(name);
121         return property;
122     }
123 
124     @Override
125     public Property setProperty(String name, Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
126         Property property = super.setProperty(name, values);
127         logActionModify(name);
128         return property;
129     }
130 
131     @Override
132     public Property setProperty(String name, String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
133         Property property = super.setProperty(name, values);
134         logActionModify(name);
135         return property;
136     }
137 
138     @Override
139     public Property setProperty(String name, String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
140         Property property = super.setProperty(name, value);
141         logActionModify(name);
142         return property;
143     }
144 
145     @Override
146     public Property setProperty(String name, InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
147         Property property = super.setProperty(name, value);
148         logActionModify(name);
149 
150         return property;
151     }
152 
153     @Override
154     public Property setProperty(String name, Binary value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
155         Property property = super.setProperty(name, value);
156         logActionModify(name);
157         return property;
158     }
159 
160     @Override
161     public Property setProperty(String name, boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
162         Property property = super.setProperty(name, value);
163         logActionModify(name);
164         return property;
165     }
166 
167     @Override
168     public Property setProperty(String name, double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
169         Property property = super.setProperty(name, value);
170         logActionModify(name);
171         return property;
172     }
173 
174     @Override
175     public Property setProperty(String name, BigDecimal value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
176         Property property = super.setProperty(name, value);
177         logActionModify(name);
178         return property;
179     }
180 
181     @Override
182     public Property setProperty(String name, long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
183         Property property = super.setProperty(name, value);
184         logActionModify(name);
185         return property;
186     }
187 
188     @Override
189     public Property setProperty(String name, Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
190         Property property = super.setProperty(name, value);
191         logActionModify(name);
192         return property;
193     }
194 
195     @Override
196     public Property setProperty(String name, Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
197         Property property = super.setProperty(name, value);
198         logActionModify(name);
199         return property;
200     }
201 
202     @Override
203     public Property setProperty(String name, Value value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
204         Property property = super.setProperty(name, value, type);
205         logActionModify(name);
206         return property;
207     }
208 
209     @Override
210     public Property setProperty(String name, Value[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
211         Property property = super.setProperty(name, values, type);
212         logActionModify(name);
213         return property;
214     }
215 
216     @Override
217     public Property setProperty(String name, String[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
218         Property property = super.setProperty(name, values, type);
219         logActionModify(name);
220         return property;
221     }
222 
223     @Override
224     public Property setProperty(String name, String value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
225         Property property = super.setProperty(name, value, type);
226         logActionModify(name);
227         return property;
228     }
229 
230     /**
231      * During node save action log all action which was done for the node and his childrens.
232      */
233     @Override
234     public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
235         super.save();
236 
237         Map<String, LinkedList<MgnlAuditLogEntry>> logMap = getContentDecorator().getLogEntries();
238         Map<String, LinkedList<MgnlAuditLogEntry>> temp = new LinkedHashMap<String, LinkedList<MgnlAuditLogEntry>>();
239         temp.putAll(logMap);
240         final String path = getPath();
241         for (Entry<String, LinkedList<MgnlAuditLogEntry>> pathLogEntries : temp.entrySet()) {
242             if (pathLogEntries.getKey().equals(path) || pathLogEntries.getKey().startsWith(path + "/")) {
243                 for (MgnlAuditLogEntry entry : pathLogEntries.getValue()) {
244                     AuditLoggingUtil.log(entry.getAction(), entry.getTimeStamp(), entry.getWorkspace(), entry.getNodeType(), entry.getPath(), entry.getPathTo());
245                 }
246                 logMap.remove(pathLogEntries.getKey());
247             }
248         }
249     }
250 
251     private void logActionModify(String name) throws RepositoryException {
252         if (name.startsWith(NodeTypes.JCR_PREFIX) || name.startsWith(NodeTypes.MGNL_PREFIX)) {
253             // do not audit system or our prop updates (same as for metadata updates in old API
254             return;
255         }
256         getContentDecorator().logActionModify(this);
257     }
258 
259 }