libreccm-legacy/ccm-ldn-importer/src/com/arsdigita/london/importer/RemoteOidMapping.java

238 lines
7.6 KiB
Java
Executable File

package com.arsdigita.london.importer;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObject;
import com.arsdigita.persistence.DataAssociation;
import com.arsdigita.persistence.DataAssociationCursor;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.metadata.ObjectType;
import com.arsdigita.persistence.metadata.Property;
import java.util.Iterator;
/**
* The mapping between source (ie those found in XML files)
* and destination (newly created on successful import) OIDs.
*
* <p>
* A RemoteOidMapping instance is actually a
* (system_id, src_oid, dst_oid) tuple. system_id is an arbitrary
* string identifying the source of import data. There is
* unique constraint on (system_id, src_oid) combination.
* </p>
* <p>
* Whenever a domain object is imported and persisted to database,
* a RemoteOidMapping instance is stored along. Tracking imported
* objects allow us to skip those already imported. As already
* mentioned, mapping is created for role properties of the imported
* content items as well, which enables us to import "shared" or
* "repository" assets that are being pointed to by more than one
* master object.
* </p>
* <p>
* Since there is absolutely no harm in running importer over the
* same data set more than once, it's trivial to sync up two or more
* CCM instances by simply importing the complete dump of one
* master node. Those already imported will be simply skipped over.
* However, keep in mind that importer never deletes objects.
* </p>
*
* @see com.arsdigita.london.importer
*/
public class RemoteOidMapping extends DomainObject {
public static final String SYSTEM_ID = "systemId";
public static final String SRC_OID = "srcOid";
public static final String DST_OID = "dstOid";
public static final String BASE_DATA_OBJECT_TYPE = RemoteOidMapping.class.getName();
/**
* Creates new RemoteOidMapping instance.
*/
public RemoteOidMapping() {
super(BASE_DATA_OBJECT_TYPE);
}
/**
* Makes persistence happy.
*/
public RemoteOidMapping(DataObject dobj) {
super(dobj);
}
/**
* Makes persistence happy camper.
*/
public RemoteOidMapping(OID mappingOID) throws DataObjectNotFoundException {
super(mappingOID);
}
/**
* Convenience constructor which creates new RemoteOidMapping instance.
*/
public RemoteOidMapping(String systemId, String srcOid, String dstOid) {
this();
setSystemId(systemId);
setSrcOid(srcOid);
setDstOid(dstOid);
}
/**
* @return null if no mapping is found.
*/
public static RemoteOidMapping retrieve(String systemId, String srcOid) {
OID oid = new OID(BASE_DATA_OBJECT_TYPE);
oid.set(SYSTEM_ID, systemId);
oid.set(SRC_OID, srcOid);
RemoteOidMapping mapping = null;
try {
mapping = new RemoteOidMapping(oid);
} catch (DataObjectNotFoundException nfe) {
// return null if none is found.
}
return mapping;
}
/**
* @return null if no mapping is found.
*/
public static String retrieveDstOid(String systemId, String srcOid) {
RemoteOidMapping mapping = retrieve(systemId, srcOid);
if (mapping == null) {
return null;
}
return mapping.getDstOid();
}
/**
* @return oid of importer object, or null if no mapping is found
*/
public static String retrieveDstOid(String systemId, OID srcOid) {
return retrieveDstOid(systemId, srcOid.toString());
}
/**
* @return true if mapping for given systemId and srcOid exists
*/
public static boolean exists(String systemId, String srcOid) {
return retrieve(systemId, srcOid) != null;
}
/**
* @return true if mapping for given systemId and srcOid exists
*/
public static boolean exists(String systemId, OID srcOid) {
return retrieve(systemId, srcOid.toString()) != null;
}
/**
* @return source OID for given system ID and destination OID,
* or null if no such mapping exists
*/
public static String retrieveSrcOid(String systemId, String dstOid) {
RemoteOidMapping map = retrieveByDstOid(systemId, dstOid);
if (map == null) {
return null;
}
return map.getSrcOid();
}
/**
* @return RemoteOidMapping for given system ID and destination OID,
* or null if no such mapping exists
*/
public static RemoteOidMapping retrieveByDstOid(String systemId, OID dstOid) {
return retrieveByDstOid(systemId, dstOid.toString());
}
/**
* @return RemoteOidMapping for given system ID and destination OID,
* or null if no such mapping exists
*/
public static RemoteOidMapping retrieveByDstOid(String systemId, String dstOid) {
DataCollection dc = SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE);
dc.addEqualsFilter(SYSTEM_ID, systemId);
dc.addEqualsFilter(DST_OID, dstOid);
if (dc.next()) {
RemoteOidMapping map = new RemoteOidMapping(dc.getDataObject());
dc.close();
return map;
}
return null;
}
public String getSystemId() {
return (String) get(SYSTEM_ID);
}
public String getSrcOid() {
return (String) get(SRC_OID);
}
public String getDstOid() {
return (String) get(DST_OID);
}
public void setSystemId(String systemId) {
set(SYSTEM_ID, systemId);
}
public void setSrcOid(String srcOid) {
set(SRC_OID, srcOid);
}
public void setDstOid(String dstOid) {
set(DST_OID, dstOid);
}
/**
* Here we will take care that all dependants get deleted
* as well. We traverse the association tree and issue
* a delete() on all mappings that exist.
*/
protected void beforeDelete() {
super.beforeDelete();
// 1. find all associated objects
// 2. check whether any of them has RemoteOidMapping
// 2a. if yes, delete the mapping
DataObject dobj = SessionManager.getSession()
.retrieve(OID.valueOf(getDstOid()));
if (dobj == null) {
return;
}
ObjectType type = dobj.getObjectType();
for (Iterator i = type.getProperties(); i.hasNext(); ) {
Property prop = (Property) i.next();
String propName = prop.getName();
Object propValue = dobj.get(propName);
if (propValue == null) {
continue;
}
if (prop.isCollection()) {
DataAssociationCursor daCursor =
((DataAssociation) propValue).getDataAssociationCursor();
while (daCursor.next()) {
OID oid = daCursor.getDataObject().getOID();
RemoteOidMapping associatedMapping = retrieveByDstOid(getSystemId(), oid);
if (associatedMapping != null) {
associatedMapping.delete();
}
}
} else if (prop.isRole()) {
OID oid = ((DataObject)propValue).getOID();
RemoteOidMapping associatedMapping = retrieveByDstOid(getSystemId(), oid);
if (associatedMapping != null) {
associatedMapping.delete();
}
}
}
}
}