/** * Licensed to the Austrian Association for Software Tool Integration (AASTI) * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. The AASTI licenses this file to you 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 org.openengsb.core.edb.jpa.internal; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.openengsb.core.edb.api.EDBDiff; import org.openengsb.core.edb.api.EDBEntry; import org.openengsb.core.edb.api.EDBException; import org.openengsb.core.edb.api.EDBObject; import org.openengsb.core.edb.api.EDBObjectDiff; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Diff implements EDBDiff { private static final Logger LOGGER = LoggerFactory.getLogger(Diff.class); private JPACommit startCommit; private JPACommit endCommit; private List<EDBObject> startState; private List<EDBObject> endState; private HashMap<String, EDBObjectDiff> diff; public Diff(JPACommit startCommit, JPACommit endCommit, List<EDBObject> startState, List<EDBObject> endState) throws EDBException { if (endCommit.getTimestamp() < startCommit.getTimestamp()) { this.startCommit = endCommit; this.endCommit = startCommit; this.startState = endState; this.endState = startState; } else { this.startCommit = startCommit; this.endCommit = endCommit; this.startState = startState; this.endState = endState; } createObjectDiffs(); LOGGER.debug("Diff created. Difference count = {}", diff.size()); } /** * Analyzes the start and end state and creates for every object that is different an objectdiff entry */ private void createObjectDiffs() throws EDBException { diff = new HashMap<String, EDBObjectDiff>(); List<EDBObject> tempList = new ArrayList<EDBObject>(); for (EDBObject o : this.endState) { tempList.add(o); } addModifiedOrDeletedObjects(tempList); addNewObjects(tempList); } /** * add all modified or deleted objects to the diff collection. As base to indicate if something changed the start * state and the list of elements from the end state is taken. */ private void addModifiedOrDeletedObjects(List<EDBObject> tempList) { for (EDBObject a : this.startState) { String oid = a.getOID(); EDBObject b = removeIfExist(oid, tempList); ObjectDiff odiff = new ObjectDiff(this.startCommit, this.endCommit, a, b); if (odiff.getDifferenceCount() > 0) { diff.put(oid, odiff); } } } /** * add all new object to the diff collection. As base to indicate if an object is new, the list of elements from the * end state which are left is taken. */ private void addNewObjects(List<EDBObject> tempList) { for (EDBObject b : tempList) { String oid = b.getOID(); ObjectDiff odiff = new ObjectDiff(this.startCommit, this.endCommit, null, b); if (odiff.getDifferenceCount() > 0) { diff.put(oid, odiff); } } } /** * Removes the element with the given oid if it exists in the list and returns it. If it not exists, null will be * returned. */ private EDBObject removeIfExist(String oid, List<EDBObject> tempList) { Iterator<EDBObject> iterator = tempList.iterator(); while (iterator.hasNext()) { EDBObject obj = iterator.next(); if (obj.getOID().equals(oid)) { iterator.remove(); return obj; } } LOGGER.debug(oid + " wasn't found in the list of end state objects"); return null; } @Override public Map<String, EDBObjectDiff> getObjectDiffs() { return diff; } @Override public final int getDifferenceCount() { return diff.size(); } @Override public ObjectDiff getDiff(String key) { return (ObjectDiff) diff.get(key); } @Override public List<EDBObject> getStartState() { return startState; } @Override public List<EDBObject> getEndState() { return endState; } @Override public JPACommit getStartCommit() { return startCommit; } @Override public JPACommit getEndCommit() { return endCommit; } @Override public String printDifferences() { StringBuilder builder = new StringBuilder(); Map<String, EDBObjectDiff> diff = this.getObjectDiffs(); for (Map.Entry<String, EDBObjectDiff> e : diff.entrySet()) { String oid = e.getKey(); builder.append("Found a difference for object: " + oid); EDBObjectDiff odiff = e.getValue(); Map<String, EDBEntry> diffMap = odiff.getDiffMap(); for (Map.Entry<String, EDBEntry> de : diffMap.entrySet()) { String key = de.getKey(); EDBEntry entry = de.getValue(); builder.append(" Entry: '").append(key).append("' from: '").append(entry.getBefore()) .append("' to: '").append(entry.getAfter()).append("'"); } builder.append("\n"); } return builder.toString(); } }