[New] Implemented opt-in audit trail in Strolch

The audit trail has its own map on the Realm and a trail is written by
realm at the end of the transaction.

You can write your own audit trail using tx.getAuditTrail().

Enable the audit trail by setting the realm configuration value
'enableAuditTrail'.
This commit is contained in:
Robert von Burg 2014-08-23 20:49:43 +02:00
parent c7a69dbf88
commit b0d921d720
23 changed files with 1202 additions and 39 deletions

View File

@ -15,13 +15,16 @@
*/
package li.strolch.model;
import ch.eitchnet.utils.helper.StringHelper;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.Audit;
import li.strolch.model.parameter.BooleanParameter;
import li.strolch.model.parameter.DateParameter;
import li.strolch.model.parameter.FloatParameter;
@ -41,6 +44,7 @@ import li.strolch.model.timevalue.impl.FloatValue;
import li.strolch.model.timevalue.impl.IntegerValue;
import li.strolch.model.timevalue.impl.StringSetValue;
import li.strolch.model.timevalue.impl.ValueChange;
import ch.eitchnet.utils.helper.StringHelper;
/**
* Class which can be used to generate objects which implement {@link StrolchElement}. These generated classes can then
@ -117,9 +121,12 @@ public class ModelGenerator {
* Creates an {@link Resource} with the given values and adds a {@link ParameterBag} by calling
* {@link #createParameterBag(String, String, String)}
*
* @param id the id of the {@link Resource}
* @param name the name of the {@link Resource}
* @param type the type of the {@link Resource}
* @param id
* the id of the {@link Resource}
* @param name
* the name of the {@link Resource}
* @param type
* the type of the {@link Resource}
*
* @return the newly created {@link Resource}
*/
@ -135,7 +142,8 @@ public class ModelGenerator {
/**
* Creates {@link StrolchTimedState} instances and adds them to the {@link Resource}
*
* @param resource the resource to which to addd the newly created {@link StrolchTimedState}
* @param resource
* the resource to which to addd the newly created {@link StrolchTimedState}
*/
public static void addTimedStates(Resource resource) {
@ -150,8 +158,7 @@ public class ModelGenerator {
// integer state
IntegerTimedState integerTimedState = new IntegerTimedState(STATE_INTEGER_ID, STATE_INTEGER_NAME);
integerTimedState.applyChange(new ValueChange<>(STATE_TIME_0,
new IntegerValue(STATE_INTEGER_TIME_0)));
integerTimedState.applyChange(new ValueChange<>(STATE_TIME_0, new IntegerValue(STATE_INTEGER_TIME_0)));
IntegerValue integerValueChange = new IntegerValue(STATE_INTEGER_TIME_10);
integerTimedState.applyChange(new ValueChange<>(STATE_TIME_10, integerValueChange));
integerTimedState.applyChange(new ValueChange<>(STATE_TIME_20, integerValueChange));
@ -160,8 +167,7 @@ public class ModelGenerator {
// boolean state
BooleanTimedState booleanTimedState = new BooleanTimedState(STATE_BOOLEAN_ID, STATE_BOOLEAN_NAME);
booleanTimedState.applyChange(new ValueChange<>(STATE_TIME_0,
new BooleanValue(STATE_BOOLEAN_TIME_0)));
booleanTimedState.applyChange(new ValueChange<>(STATE_TIME_0, new BooleanValue(STATE_BOOLEAN_TIME_0)));
BooleanValue booleanValueChange = new BooleanValue(STATE_BOOLEAN_TIME_10);
booleanTimedState.applyChange(new ValueChange<>(STATE_TIME_10, booleanValueChange));
booleanValueChange = booleanValueChange.getInverse();
@ -207,11 +213,16 @@ public class ModelGenerator {
* Creates a list of {@link Resource Resources} with the given values and adds a {@link ParameterBag} by calling
* {@link #createParameterBag(String, String, String)}
*
* @param idStart id range start
* @param count the number of elements to create
* @param idPrefix the prefix to generate IDs for the {@link Resource Resources}
* @param name the name of the {@link Resource}
* @param type the type of the {@link Resource}
* @param idStart
* id range start
* @param count
* the number of elements to create
* @param idPrefix
* the prefix to generate IDs for the {@link Resource Resources}
* @param name
* the name of the {@link Resource}
* @param type
* the type of the {@link Resource}
*
* @return the list of newly created {@link Resource Resources}
*/
@ -228,9 +239,12 @@ public class ModelGenerator {
* Creates an {@link Order} with the given values and adds a {@link ParameterBag} by calling
* {@link #createParameterBag(String, String, String)}
*
* @param id the id of the {@link Order}
* @param name the name of the {@link Order}
* @param type the type of the {@link Order}
* @param id
* the id of the {@link Order}
* @param name
* the name of the {@link Order}
* @param type
* the type of the {@link Order}
*
* @return the newly created {@link Order}
*/
@ -242,11 +256,16 @@ public class ModelGenerator {
* Creates an {@link Order} with the given values and adds a {@link ParameterBag} by calling
* {@link #createParameterBag(String, String, String)}
*
* @param id the id of the {@link Order}
* @param name the name of the {@link Order}
* @param type the type of the {@link Order}
* @param date the date of the {@link Order}
* @param state the {@link State} of the {@link Order}
* @param id
* the id of the {@link Order}
* @param name
* the name of the {@link Order}
* @param type
* the type of the {@link Order}
* @param date
* the date of the {@link Order}
* @param state
* the {@link State} of the {@link Order}
*
* @return the newly created {@link Order}
*/
@ -263,11 +282,16 @@ public class ModelGenerator {
* Creates a list of {@link Order Orders} with the given values and adds a {@link ParameterBag} by calling
* {@link #createParameterBag(String, String, String)}
*
* @param idStart id range start
* @param count the number of elements to create
* @param idPrefix the prefix to generate IDs for the {@link Order Orders}
* @param name the name of the {@link Order}
* @param type the type of the {@link Order}
* @param idStart
* id range start
* @param count
* the number of elements to create
* @param idPrefix
* the prefix to generate IDs for the {@link Order Orders}
* @param name
* the name of the {@link Order}
* @param type
* the type of the {@link Order}
*
* @return the list of newly created {@link Order Orders}
*/
@ -284,9 +308,12 @@ public class ModelGenerator {
* Creates a {@link ParameterBag} with the given values and calls {@link #addAllParameters(ParameterBag)} to add
* {@link Parameter}s
*
* @param id the id of the {@link ParameterBag}
* @param name the name of the {@link ParameterBag}
* @param type the type of the {@link ParameterBag}
* @param id
* the id of the {@link ParameterBag}
* @param name
* the name of the {@link ParameterBag}
* @param type
* the type of the {@link ParameterBag}
*
* @return the newly created {@link ParameterBag}
*/
@ -345,4 +372,33 @@ public class ModelGenerator {
stringListP.setIndex(7);
bag.addParameter(stringListP);
}
private static String randomValue(Random rand, String[] values) {
return values[rand.nextInt(values.length)];
}
public static Audit randomAudit() {
Random rand = new Random(234234L);
String[] usernames = new String[] { "bob", "alice", "jenny" };
String[] firstnames = new String[] { "Bob", "Alice", "Jenny" };
String[] lastnames = new String[] { "Richards", "Kennedy", "Davids" };
String[] types = new String[] { Tags.RESOURCE, Tags.ORDER, Tags.AUDIT };
String[] actions = new String[] { "AddResourceService", "UpdateResourceService", "RemoveResourceService",
"AddOrderService", "UpdateOrderService", "RemoveOrderService" };
Audit audit = new Audit();
audit.setId(StringHelper.getUniqueIdLong());
audit.setUsername(randomValue(rand, usernames));
audit.setFirstname(randomValue(rand, firstnames));
audit.setLastname(randomValue(rand, lastnames));
audit.setDate(new Date(rand.nextInt(5000)));
audit.setElementType(randomValue(rand, types));
audit.setElementAccessed(StringHelper.getUniqueId());
audit.setNewVersion(new Date(rand.nextInt(5000)));
audit.setAction(randomValue(rand, actions));
audit.setAccessType(AccessType.values()[rand.nextInt(AccessType.values().length)]);
return audit;
}
}

View File

@ -112,7 +112,8 @@ public class Order extends GroupedParameterizedElement implements StrolchRootEle
}
/**
* @param date the date to set
* @param date
* the date to set
*/
public void setDate(Date date) {
this.date = date;
@ -126,7 +127,8 @@ public class Order extends GroupedParameterizedElement implements StrolchRootEle
}
/**
* @param state the state to set
* @param state
* the state to set
*/
public void setState(State state) {
this.state = state;
@ -179,7 +181,7 @@ public class Order extends GroupedParameterizedElement implements StrolchRootEle
}
@Override
public <T> T accept(StrolchRootElementVisitor visitor) {
public <T> T accept(StrolchRootElementVisitor<T> visitor) {
return visitor.visitOrder(this);
}

View File

@ -198,7 +198,7 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot
}
@Override
public <T> T accept(StrolchRootElementVisitor visitor) {
public <T> T accept(StrolchRootElementVisitor<T> visitor) {
return visitor.visitResource(this);
}

View File

@ -25,5 +25,5 @@ import li.strolch.model.visitor.StrolchRootElementVisitor;
*/
public interface StrolchRootElement extends StrolchElement {
public <T> T accept(StrolchRootElementVisitor visitor);
public <T> T accept(StrolchRootElementVisitor<T> visitor);
}

View File

@ -39,6 +39,22 @@ public class Tags {
public static final String STROLCH_MODEL = "StrolchModel";
public static final String INCLUDE_FILE = "IncludeFile";
public static final String FILE = "file";
public static final String BAG = "Bag";
public static final String AUDIT = "Audit";
public class Audit {
public static final String ID = Tags.ID;
public static final String USERNAME = "Username";
public static final String FIRSTNAME = "Firstname";
public static final String LASTNAME = "Lastname";
public static final String DATE = "Date";
public static final String ELEMENT_TYPE = "ElementType";
public static final String ELEMENT_ACCESSED = "ElementAccessed";
public static final String NEW_VERSION = "NewVersion";
public static final String ACTION = "Action";
public static final String ACCESS_TYPE = "AccessType";
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import li.strolch.model.StrolchRootElement;
/**
* Defines the type of access performed on a {@link StrolchRootElement}
*
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public enum AccessType {
READ, CREATE, UPDATE, DELETE;
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import li.strolch.model.query.StringMatchMode;
import li.strolch.model.query.StringSelection;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class ActionSelection extends AuditSelection {
private StringSelection actionSelection;
private AccessType[] accessTypes;
public ActionSelection(AuditQuery query) {
super(query);
}
public ActionSelection actions(StringMatchMode matchMode, String... actions) {
this.actionSelection = new StringSelection(matchMode, actions);
return this;
}
public ActionSelection accessTypes(AccessType... accessTypes) {
this.accessTypes = accessTypes;
return this;
}
public AccessType[] getAccessTypes() {
return this.accessTypes;
}
public boolean isWildcardActionType() {
return this.accessTypes == null || this.accessTypes.length == 0;
}
public boolean isWildcardAction() {
return this.actionSelection == null || this.actionSelection.isWildCard();
}
@Override
public void accept(AuditQueryVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -0,0 +1,233 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import java.io.Serializable;
import java.util.Date;
import li.strolch.model.StrolchRootElement;
/**
* Used to log/audit access to {@link StrolchRootElement}
*
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class Audit implements Comparable<Audit>, Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String firstname;
private String lastname;
private Date date;
private String elementType;
private String elementAccessed;
private Date newVersion;
private String action;
private AccessType accessType;
/**
* @return the id
*/
public Long getId() {
return this.id;
}
/**
* @param id
* the id to set
*/
public void setId(long id) {
this.id = id;
}
/**
* @return the username
*/
public String getUsername() {
return this.username;
}
/**
* @param username
* the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* @return the firstname
*/
public String getFirstname() {
return this.firstname;
}
/**
* @param firstname
* the firstname to set
*/
public void setFirstname(String firstname) {
this.firstname = firstname;
}
/**
* @return the lastname
*/
public String getLastname() {
return this.lastname;
}
/**
* @param lastname
* the lastname to set
*/
public void setLastname(String lastname) {
this.lastname = lastname;
}
/**
* @return the date
*/
public Date getDate() {
return this.date;
}
/**
* @param date
* the date to set
*/
public void setDate(Date date) {
this.date = date;
}
/**
* @return the elementType
*/
public String getElementType() {
return this.elementType;
}
/**
* @param elementType
* the elementType to set
*/
public void setElementType(String elementType) {
this.elementType = elementType;
}
/**
* @return the elementAccessed
*/
public String getElementAccessed() {
return this.elementAccessed;
}
/**
* @param elementAccessed
* the elementAccessed to set
*/
public void setElementAccessed(String elementAccessed) {
this.elementAccessed = elementAccessed;
}
/**
* @return the newVersion
*/
public Date getNewVersion() {
return this.newVersion;
}
/**
* @param newVersion
* the newVersion to set
*/
public void setNewVersion(Date newVersion) {
this.newVersion = newVersion;
}
/**
* @return the action
*/
public String getAction() {
return this.action;
}
/**
* @param action
* the action to set
*/
public void setAction(String action) {
this.action = action;
}
/**
* @return the accessType
*/
public AccessType getAccessType() {
return this.accessType;
}
/**
* @param accessType
* the accessType to set
*/
public void setAccessType(AccessType accessType) {
this.accessType = accessType;
}
public <U> U accept(AuditVisitor<U> visitor) {
return visitor.visitAudit(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Audit other = (Audit) obj;
if (this.id == null) {
if (other.id != null) {
return false;
}
} else if (!this.id.equals(other.id)) {
return false;
}
return true;
}
@Override
public int compareTo(Audit o) {
return getId().compareTo(o.getId());
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import java.text.MessageFormat;
import li.strolch.model.Tags;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import ch.eitchnet.utils.dbc.DBC;
import ch.eitchnet.utils.iso8601.ISO8601FormatFactory;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class AuditFromDomReader {
public Audit from(Element rootElement) {
Audit audit = new Audit();
String idS = rootElement.getAttribute(Tags.Audit.ID);
DBC.INTERIM.assertNotEmpty("Id must be set!", idS);
audit.setId(Long.valueOf(idS));
NodeList childNodes = rootElement.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
if (!(item instanceof Element))
continue;
Element element = (Element) item;
String nodeName = element.getNodeName();
String txtContent = element.getTextContent();
switch (nodeName) {
case Tags.Audit.USERNAME:
audit.setUsername(txtContent);
break;
case Tags.Audit.FIRSTNAME:
audit.setFirstname(txtContent);
break;
case Tags.Audit.LASTNAME:
audit.setLastname(txtContent);
break;
case Tags.Audit.DATE:
audit.setDate(ISO8601FormatFactory.getInstance().getXmlDateFormat().parse(txtContent));
break;
case Tags.Audit.ELEMENT_TYPE:
audit.setElementType(txtContent);
break;
case Tags.Audit.ELEMENT_ACCESSED:
audit.setElementAccessed(txtContent);
break;
case Tags.Audit.NEW_VERSION:
audit.setNewVersion(ISO8601FormatFactory.getInstance().getXmlDateFormat().parse(txtContent));
break;
case Tags.Audit.ACTION:
audit.setAction(txtContent);
break;
case Tags.Audit.ACCESS_TYPE:
audit.setAccessType(AccessType.valueOf(txtContent));
break;
default:
throw new IllegalArgumentException(MessageFormat.format("Unhandled/Invalid tag {0} for Audit {1}",
nodeName, idS));
}
}
String msg = " missing for element with id " + audit.getId();
DBC.INTERIM.assertNotEmpty("Username" + msg, audit.getUsername());
DBC.INTERIM.assertNotEmpty("Firstname" + msg, audit.getFirstname());
DBC.INTERIM.assertNotEmpty("Lastname" + msg, audit.getLastname());
DBC.INTERIM.assertNotNull("Date" + msg, audit.getDate());
DBC.INTERIM.assertNotEmpty("ElementType" + msg, audit.getElementType());
DBC.INTERIM.assertNotEmpty("ElementAccessed" + msg, audit.getElementAccessed());
//DBC.INTERIM.assertNotNull("NewVersion" + msg, audit.getNewVersion());
DBC.INTERIM.assertNotEmpty("Action" + msg, audit.getAction());
DBC.INTERIM.assertNotNull("AccessType" + msg, audit.getAccessType());
return audit;
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import java.util.ArrayList;
import java.util.List;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class AuditQuery {
private int maxResults;
private List<AuditSelection> selections;
public AuditQuery() {
this.selections = new ArrayList<>();
}
/**
* @return the maxResults
*/
public int getMaxResults() {
return this.maxResults;
}
/**
* @param maxResults
* the maxResults to set
*/
public void setMaxResults(int maxResults) {
this.maxResults = maxResults;
}
public ActionSelection action() {
ActionSelection selection = new ActionSelection(this);
this.selections.add(selection);
return selection;
}
public DateRangeSelection dateRange() {
DateRangeSelection selection = new DateRangeSelection(this);
this.selections.add(selection);
return selection;
}
public ElementSelection element() {
ElementSelection selection = new ElementSelection(this);
this.selections.add(selection);
return selection;
}
public IdentitySelection identity() {
IdentitySelection selection = new IdentitySelection(this);
this.selections.add(selection);
return selection;
}
public void accept(AuditQueryVisitor visitor) {
visitor.visit(this);
for (AuditSelection selection : selections) {
selection.accept(visitor);
}
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public interface AuditQueryVisitor {
public void visit(ElementSelection selection);
public void visit(IdentitySelection selection);
public void visit(DateRangeSelection selection);
public void visit(ActionSelection selection);
public void visit(AuditQuery auditQuery);
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import org.xml.sax.helpers.DefaultHandler;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class AuditSaxReader extends DefaultHandler {
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public abstract class AuditSelection {
private AuditQuery query;
public AuditSelection(AuditQuery query) {
super();
this.query = query;
}
public AuditQuery query() {
return this.query;
}
public abstract void accept(AuditQueryVisitor visitor);
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import javax.xml.parsers.DocumentBuilder;
import li.strolch.model.Tags;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import ch.eitchnet.utils.helper.DomUtil;
import ch.eitchnet.utils.iso8601.ISO8601FormatFactory;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class AuditToDomVisitor implements AuditVisitor<Document> {
@Override
public Document visitAudit(Audit audit) {
DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder();
Document doc = documentBuilder.getDOMImplementation().createDocument(null, null, null);
Element auditE = doc.createElement(Tags.AUDIT);
auditE.setAttribute(Tags.Audit.ID, audit.getId().toString());
auditE.appendChild(elem(doc, Tags.Audit.USERNAME, audit.getUsername()));
auditE.appendChild(elem(doc, Tags.Audit.FIRSTNAME, audit.getUsername()));
auditE.appendChild(elem(doc, Tags.Audit.LASTNAME, audit.getUsername()));
auditE.appendChild(elem(doc, Tags.Audit.DATE, ISO8601FormatFactory.getInstance().formatDate(audit.getDate())));
auditE.appendChild(elem(doc, Tags.Audit.ELEMENT_TYPE, audit.getElementType()));
auditE.appendChild(elem(doc, Tags.Audit.ELEMENT_ACCESSED, audit.getElementAccessed()));
if (audit.getNewVersion() != null)
auditE.appendChild(elem(doc, Tags.Audit.NEW_VERSION,
ISO8601FormatFactory.getInstance().formatDate(audit.getNewVersion())));
auditE.appendChild(elem(doc, Tags.Audit.ACTION, audit.getAction()));
auditE.appendChild(elem(doc, Tags.Audit.ACCESS_TYPE, audit.getAccessType().name()));
doc.appendChild(auditE);
return doc;
}
private Element elem(Document doc, String tag, String txtValue) {
Element element = doc.createElement(tag);
element.setTextContent(txtValue);
return element;
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public interface AuditVisitor<U> {
public U visitAudit(Audit audit);
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import java.util.Date;
import ch.eitchnet.utils.collections.DateRange;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class DateRangeSelection extends AuditSelection {
private DateRange dateRange;
public DateRangeSelection(AuditQuery query) {
super(query);
}
public DateRange from(Date from, boolean inclusive) {
return this.dateRange.from(from, inclusive);
}
public DateRange to(Date to, boolean inclusive) {
return this.dateRange.to(to, inclusive);
}
public Date getFromDate() {
return this.dateRange.getFromDate();
}
public Date getToDate() {
return this.dateRange.getToDate();
}
public boolean isFromBounded() {
return this.dateRange.isFromBounded();
}
public boolean isToBounded() {
return this.dateRange.isToBounded();
}
public boolean isUnbounded() {
return this.dateRange.isUnbounded();
}
public boolean isBounded() {
return this.dateRange.isBounded();
}
public boolean contains(Date date) {
return this.dateRange.contains(date);
}
@Override
public void accept(AuditQueryVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import li.strolch.model.query.StringMatchMode;
import li.strolch.model.query.StringSelection;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class ElementSelection extends AuditSelection {
private StringSelection elementTypeSelection;
private StringSelection elementAccessedSelection;
public ElementSelection(AuditQuery query) {
super(query);
}
public ElementSelection elementTypes(StringMatchMode matchMode, String... elementTypes) {
this.elementTypeSelection = new StringSelection(matchMode, elementTypes);
return this;
}
public ElementSelection elementsAccessed(StringMatchMode matchMode, String... elementsAccessed) {
this.elementAccessedSelection = new StringSelection(matchMode, elementsAccessed);
return this;
}
public StringSelection getElementAccessedSelection() {
return this.elementAccessedSelection;
}
public StringSelection getElementTypeSelection() {
return this.elementTypeSelection;
}
public boolean isElementTypesWildcard() {
return this.elementTypeSelection == null || this.elementTypeSelection.isWildCard();
}
public boolean isElementsAccessedWildcard() {
return this.elementAccessedSelection == null || this.elementAccessedSelection.isWildCard();
}
@Override
public void accept(AuditQueryVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
import li.strolch.model.query.StringMatchMode;
import li.strolch.model.query.StringSelection;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class IdentitySelection extends AuditSelection {
private StringSelection usernameSelection;
private StringSelection firstnameSelection;
private StringSelection lastnameSelection;
public IdentitySelection(AuditQuery query) {
super(query);
}
public IdentitySelection usernames(StringMatchMode matchMode, String... usernames) {
this.usernameSelection = new StringSelection(matchMode, usernames);
return this;
}
public IdentitySelection firstnames(StringMatchMode matchMode, String... firstnames) {
this.firstnameSelection = new StringSelection(matchMode, firstnames);
return this;
}
public IdentitySelection lastnames(StringMatchMode matchMode, String... lastnames) {
this.lastnameSelection = new StringSelection(matchMode, lastnames);
return this;
}
/**
* @return the firstnameSelection
*/
public StringSelection getFirstnameSelection() {
return this.firstnameSelection;
}
/**
* @return the lastnameSelection
*/
public StringSelection getLastnameSelection() {
return this.lastnameSelection;
}
/**
* @return the usernameSelection
*/
public StringSelection getUsernameSelection() {
return this.usernameSelection;
}
public boolean isFirstnameWildcard() {
return this.firstnameSelection == null || this.firstnameSelection.isWildCard();
}
public boolean isLastnameWildcard() {
return this.lastnameSelection == null || this.lastnameSelection.isWildCard();
}
public boolean isUsernameWildcard() {
return this.usernameSelection == null || this.usernameSelection.isWildCard();
}
@Override
public void accept(AuditQueryVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.audit;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class NoStrategyAuditVisitor implements AuditVisitor<Audit> {
@Override
public Audit visitAudit(Audit audit) {
return audit;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.query;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public enum StringMatchMode {
EQUALS_CASE_SENSITIVE(true, true),
EQUALS_CASE_INSENSITIVE(true, false),
CONTAINS_CASE_SENSITIVE(false, true),
CONTAINS_CASE_INSENSITIVE(false, false);
private final boolean equals;
private final boolean caseSensitve;
private StringMatchMode(boolean equals, boolean caseSensitive) {
this.equals = equals;
this.caseSensitve = caseSensitive;
}
/**
* @return the caseSensitve
*/
public boolean isCaseSensitve() {
return this.caseSensitve;
}
/**
* @return the equals
*/
public boolean isEquals() {
return this.equals;
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.query;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class StringSelection {
private StringMatchMode matchMode;
private String[] values;
public StringSelection() {
//
}
/**
* @param matchMode
* @param values
*/
public StringSelection(StringMatchMode matchMode, String[] values) {
this.matchMode = matchMode;
this.values = values;
}
/**
* @return the matchMode
*/
public StringMatchMode getMatchMode() {
return this.matchMode;
}
/**
* @param matchMode
* the matchMode to set
*/
public void setMatchMode(StringMatchMode matchMode) {
this.matchMode = matchMode;
}
/**
* @return the values
*/
public String[] getValues() {
return this.values;
}
/**
* @param values
* the values to set
*/
public void setValues(String... values) {
this.values = values;
}
/**
* @return
*/
public boolean isWildCard() {
return this.values == null || this.values.length == 0;
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.visitor;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class ElementTypeVisitor implements StrolchRootElementVisitor<String> {
@Override
public String visitOrder(Order order) {
return Tags.ORDER;
}
@Override
public String visitResource(Resource resource) {
return Tags.RESOURCE;
}
}

View File

@ -21,9 +21,9 @@ import li.strolch.model.Resource;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public interface StrolchRootElementVisitor extends StrolchVisitor {
public interface StrolchRootElementVisitor<T> extends StrolchVisitor {
public <T> T visitOrder(Order order);
public T visitOrder(Order order);
public <T> T visitResource(Resource resource);
public T visitResource(Resource resource);
}