/******************************************************************************* * Copyright 2005-2007, CHISEL Group, University of Victoria, Victoria, BC, Canada * and IBM Corporation. All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * The Chisel Group, University of Victoria *******************************************************************************/ package net.sourceforge.tagsea.resources.synchronize; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import net.sourceforge.tagsea.TagSEAPlugin; import net.sourceforge.tagsea.resources.IResourceWaypointAttributes; import net.sourceforge.tagsea.resources.ResourceWaypointPlugin; import net.sourceforge.tagsea.resources.waypoints.IMutableResourceWaypointDescriptor; import net.sourceforge.tagsea.resources.waypoints.IResourceWaypointDescriptor; import net.sourceforge.tagsea.resources.waypoints.ResourceWaypointDelegate; import net.sourceforge.tagsea.resources.waypoints.ResourceWaypointProxyDescriptor; import net.sourceforge.tagsea.resources.waypoints.operations.CreateWaypointOperation; import net.sourceforge.tagsea.resources.waypoints.xml.ResourceWaypointDescriptor; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.xml.sax.SAXException; public class WaypointSynchronizeObject { private IResourceWaypointDescriptor local; private IResourceWaypointDescriptor remote; private IProject project; private long latestRevision; public final static int NEW_IN = 0; public final static int NEW_OUT = 1; public final static int REMOVE_IN = 2; public final static int REMOVE_OUT = 3; public final static int SYNCH_IN = 4; public final static int SYNCH_OUT = 5; public final static int CONFLICT = 6; public final static int EQUAL = 7; public class ValueComparison { public static final String TAGS_ATTR = "net.sourceforge.tagsea.resources.synchronize.tags.attribute"; private String attribute; public ValueComparison(String attribute) { this.attribute = attribute; } public WaypointSynchronizeObject getSync() { return WaypointSynchronizeObject.this; } public Object getLocalValue() { if (getLocal() == null) { return null; } return getValue(getLocal()); } public Object getRemoteValue() { if (getRemote() == null) { return null; } return getValue(getRemote()); } public void copyLeft() { if (local == null) { IMutableResourceWaypointDescriptor desc = new ResourceWaypointDescriptor(); desc.setRevision(latestRevision+""); local = desc; } if (local instanceof IMutableResourceWaypointDescriptor) { IMutableResourceWaypointDescriptor desc = (IMutableResourceWaypointDescriptor) local; copyValue(getRemote(), desc); } } public void copyRight() { if (remote == null) { IMutableResourceWaypointDescriptor desc = new ResourceWaypointDescriptor(); desc.setRevision(latestRevision+""); remote = desc; } if (remote instanceof IMutableResourceWaypointDescriptor) { IMutableResourceWaypointDescriptor desc = (IMutableResourceWaypointDescriptor) remote; copyValue(getLocal(), desc); } } /** * @param remote * @param desc */ private void copyValue(IResourceWaypointDescriptor source, IMutableResourceWaypointDescriptor dest) { if (IResourceWaypointAttributes.ATTR_AUTHOR.equals(attribute)) { dest.setAuthor(source.getAuthor()); } else if (IResourceWaypointAttributes.ATTR_CHAR_END.equals(attribute)) { dest.setCharEnd(source.getCharEnd()); } else if (IResourceWaypointAttributes.ATTR_CHAR_START.equals(attribute)) { dest.setCharStart(source.getCharStart()); } else if (IResourceWaypointAttributes.ATTR_DATE.equals(attribute)) { dest.setDate(source.getDate()); } else if (IResourceWaypointAttributes.ATTR_LINE.equals(attribute)) { dest.setLine(source.getLine()); } else if (IResourceWaypointAttributes.ATTR_MESSAGE.equals(attribute)) { dest.setText(source.getText()); } else if (IResourceWaypointAttributes.ATTR_RESOURCE.equals(attribute)) { dest.setResource(source.getResource()); } else if (IResourceWaypointAttributes.ATTR_STAMP.equals(attribute)) { dest.setStamp(source.getStamp()); } else if (TAGS_ATTR.equals(attribute)) { dest.setTags(source.getTags()); } //update the revision of the destination to the latest revision value of the two. Date sourceDate = new Date(Long.parseLong(source.getRevision())); Date destDate = new Date(Long.parseLong(dest.getRevision())); if (destDate.before(sourceDate)) { dest.setRevision(source.getRevision()); } } /** * @param local * @return */ private Object getValue(IResourceWaypointDescriptor desc) { if (IResourceWaypointAttributes.ATTR_AUTHOR.equals(attribute)) { return desc.getAuthor(); } else if (IResourceWaypointAttributes.ATTR_CHAR_END.equals(attribute)) { return desc.getCharEnd(); } else if (IResourceWaypointAttributes.ATTR_CHAR_START.equals(attribute)) { return desc.getCharStart(); } else if (IResourceWaypointAttributes.ATTR_DATE.equals(attribute)) { return desc.getDate(); } else if (IResourceWaypointAttributes.ATTR_LINE.equals(attribute)) { return desc.getLine(); } else if (IResourceWaypointAttributes.ATTR_MESSAGE.equals(attribute)) { return desc.getText(); } else if (IResourceWaypointAttributes.ATTR_RESOURCE.equals(attribute)) { return desc.getResource(); } else if (IResourceWaypointAttributes.ATTR_REVISION.equals(attribute)) { return desc.getRevision(); } else if (IResourceWaypointAttributes.ATTR_STAMP.equals(attribute)) { return desc.getStamp(); } else if (TAGS_ATTR.equals(attribute)) { return desc.getTags(); } return null; } /** * Returns the attribute that is being compared. * @return the attribute */ public String getAttribute() { return attribute; } /** * Returns true iff this comparison object compares tags. * @return */ public boolean comparesTags() { return TAGS_ATTR.equals(getAttribute()); } } public WaypointSynchronizeObject(IProject project, long workspaceRevision, IResourceWaypointDescriptor local, IResourceWaypointDescriptor remote) { this.project = project; this.local = local; this.remote = remote; this.latestRevision = workspaceRevision; } /** * @return the local */ public IResourceWaypointDescriptor getLocal() { return local; } /** * @return the remote */ public IResourceWaypointDescriptor getRemote() { return remote; } /** * @return the project */ public IProject getProject() { return project; } public long getWorkspaceRevision() { return latestRevision; } public int getKind() { Date localDate = null; Date remoteDate = null; Date workspaceDate = new Date(latestRevision); if (getLocal() != null) { long lr = Long.parseLong(getLocal().getRevision()); localDate = new Date(lr); } if (getRemote() != null) { long rr = Long.parseLong(getRemote().getRevision()); remoteDate = new Date(rr); } if (remoteDate == null) { if (localDate.before(workspaceDate)) { return REMOVE_IN; } return NEW_OUT; } else if (localDate == null) { if (remoteDate.before(workspaceDate)) { return REMOVE_OUT; } return NEW_IN; } else { if (remoteDate.before(localDate)) { return SYNCH_OUT; } else if (localDate.before(remoteDate)) { return SYNCH_IN; } else { boolean same = getLocal().getAuthor().equals(getRemote().getAuthor()); same &= getLocal().getCharEnd()==(getRemote().getCharEnd()); same &= getLocal().getCharStart()==getRemote().getCharStart(); same &= getLocal().getDate().equals(getRemote().getDate()); same &= getLocal().getLine()==getRemote().getLine(); same &= getLocal().getResource().equals(getRemote().getResource()); same &= getLocal().getText().equals(getRemote().getText()); same &= getLocal().getTags().equals(getRemote().getTags()); if (same) { return EQUAL; } } } return CONFLICT; } /** * Copies all the values from the remote object to the local one. */ public void checkout() { if (local == null) { IMutableResourceWaypointDescriptor desc = new ResourceWaypointDescriptor(); desc.setRevision(latestRevision+""); local = desc; } copyValues(getRemote(), (IMutableResourceWaypointDescriptor) getLocal()); } /** * Copies all the values from the local object to the remote one. * */ public void checkIn() { if (remote == null) { IMutableResourceWaypointDescriptor desc = new ResourceWaypointDescriptor(); desc.setRevision(latestRevision+""); remote = desc; } copyValues(getLocal(), (IMutableResourceWaypointDescriptor) getRemote()); } /** * Commits the changes. * */ public IStatus commit() { if (getRemote() == null || getLocal() == null) { return new Status(IStatus.ERROR, ResourceWaypointPlugin.PLUGIN_ID, IStatus.ERROR, "Null value", null); } if (getLocal() instanceof ResourceWaypointProxyDescriptor) { ((ResourceWaypointProxyDescriptor)getLocal()).commit(); } else { CreateWaypointOperation createOp = new CreateWaypointOperation(getLocal()); //create a new waypoint TagSEAPlugin.run(createOp, true); if (!createOp.getStatus().isOK()) { return createOp.getStatus(); } } List<IResourceWaypointDescriptor> descriptors = new ArrayList<IResourceWaypointDescriptor>(1); descriptors.add(getRemote()); Exception ex = null; try { WaypointSynchronizerHelp.INSTANCE.updateSynchronizeInfo(project, descriptors, new NullProgressMonitor()); } catch (IOException e) { ResourceWaypointPlugin.getDefault().log(e); ex = e; } catch (SAXException e) { ResourceWaypointPlugin.getDefault().log(e); ex = e; } if (ex != null) { String message = ex.getMessage(); if (message == null) { message = ""; } return new Status( IStatus.ERROR, ResourceWaypointPlugin.PLUGIN_ID, IStatus.ERROR, message, ex ); } return Status.OK_STATUS; } /** * Copies all of the values from the source to the destination. * @param source * @param dest */ private void copyValues(IResourceWaypointDescriptor source, IMutableResourceWaypointDescriptor dest) { dest.setText(source.getText()); dest.setAuthor(source.getAuthor()); dest.setCharEnd(source.getCharEnd()); dest.setCharStart(source.getCharStart()); dest.setDate(source.getDate()); dest.setLine(source.getLine()); dest.setResource(source.getResource()); dest.setStamp(source.getStamp()); dest.setTags(source.getTags()); // update the revision of the destination to the latest revision value of the two. Date sourceDate = new Date(Long.parseLong(source.getRevision())); Date destDate = new Date(Long.parseLong(dest.getRevision())); if (destDate.before(sourceDate)) { dest.setRevision(source.getRevision()); } } /** * Returns a comparison object for the specified attribute. See IResourceWaypointAttributes for the * available attributes. * @param attribute * @return */ public ValueComparison getValueComparison(String attribute) { return new ValueComparison(attribute); } /** * Returns a comparison for the tags in the local and remote copies of the waypoint. * @return a comparison for the tags in the local and remote copies of the waypoint. */ public ValueComparison getTagsComparison() { return new ValueComparison(ValueComparison.TAGS_ATTR); } }