PublishedLink
So... jetzt sollten die Link-Attribute auch bei Links zwischen top-level ContentItems übernommen werden. git-svn-id: https://svn.libreccm.org/ccm/trunk@589 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
afd350c7b9
commit
53e63abbc3
|
|
@ -22,15 +22,13 @@ model com.arsdigita.cms;
|
||||||
import com.arsdigita.kernel.ACSObject;
|
import com.arsdigita.kernel.ACSObject;
|
||||||
|
|
||||||
object type PublishedLink {
|
object type PublishedLink {
|
||||||
composite ContentItem[1..1] pending =
|
composite ContentItem[1..1] pending = join cms_published_links.pending to cms_items.item_id;
|
||||||
join cms_published_links.pending to cms_items.item_id;
|
|
||||||
// change this later?
|
// change this later?
|
||||||
// OID[1..1] pendingOID;
|
// OID[1..1] pendingOID;
|
||||||
ACSObject[1..1] pendingSource =
|
ACSObject[1..1] pendingSource = join cms_published_links.pending_source to acs_objects.object_id;
|
||||||
join cms_published_links.pending_source to acs_objects.object_id;
|
String[1..1] propertyName = cms_published_links.property_name VARCHAR(100);
|
||||||
String[1..1] propertyName = cms_published_links.property_name VARCHAR(100);
|
composite ContentItem[1..1] draftTarget = join cms_published_links.draft_target to cms_items.item_id;
|
||||||
composite ContentItem[1..1] draftTarget =
|
Blob[0..1] linkAttributes = cms_published_links.link_attributes BLOB;
|
||||||
join cms_published_links.draft_target to cms_items.item_id;
|
|
||||||
object key(pending, pendingSource, propertyName, draftTarget);
|
object key(pending, pendingSource, propertyName, draftTarget);
|
||||||
aggressive load (pending.id, pendingSource.id, draftTarget.id);
|
aggressive load (pending.id, pendingSource.id, draftTarget.id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,12 @@ import com.arsdigita.persistence.SessionManager;
|
||||||
import com.arsdigita.persistence.metadata.ObjectType;
|
import com.arsdigita.persistence.metadata.ObjectType;
|
||||||
import com.arsdigita.persistence.metadata.Property;
|
import com.arsdigita.persistence.metadata.Property;
|
||||||
import com.arsdigita.util.Assert;
|
import com.arsdigita.util.Assert;
|
||||||
import com.redhat.persistence.DuplicateObjectException;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
|
@ -51,18 +56,17 @@ import java.util.Set;
|
||||||
class PublishedLink extends DomainObject {
|
class PublishedLink extends DomainObject {
|
||||||
|
|
||||||
private static final Logger s_log = Logger.getLogger(PublishedLink.class);
|
private static final Logger s_log = Logger.getLogger(PublishedLink.class);
|
||||||
|
|
||||||
static final String SOURCE_MASTER_ITEM = "pending";
|
static final String SOURCE_MASTER_ITEM = "pending";
|
||||||
|
|
||||||
// replace below later with:
|
// replace below later with:
|
||||||
//public static final String PENDING_OID = "pendingOID"
|
//public static final String PENDING_OID = "pendingOID"
|
||||||
static final String PENDING_SOURCE = "pendingSource";
|
static final String PENDING_SOURCE = "pendingSource";
|
||||||
static final String PROPERTY_NAME = "propertyName";
|
static final String PROPERTY_NAME = "propertyName";
|
||||||
static final String DRAFT_TARGET = "draftTarget";
|
static final String DRAFT_TARGET = "draftTarget";
|
||||||
|
static final String LINK_ATTRIBUTES = "linkAttributes";
|
||||||
static final String BASE_DATA_OBJECT_TYPE =
|
static final String BASE_DATA_OBJECT_TYPE =
|
||||||
"com.arsdigita.cms.PublishedLink";
|
"com.arsdigita.cms.PublishedLink";
|
||||||
|
|
||||||
|
@Override
|
||||||
protected String getBaseDataObjectType() {
|
protected String getBaseDataObjectType() {
|
||||||
return BASE_DATA_OBJECT_TYPE;
|
return BASE_DATA_OBJECT_TYPE;
|
||||||
}
|
}
|
||||||
|
|
@ -122,9 +126,10 @@ class PublishedLink extends DomainObject {
|
||||||
* one already exists for these items.
|
* one already exists for these items.
|
||||||
*/
|
*/
|
||||||
static PublishedLink create(ContentItem sourceMasterItem,
|
static PublishedLink create(ContentItem sourceMasterItem,
|
||||||
DomainObject linkSource,
|
DomainObject linkSource,
|
||||||
String propertyName,
|
String propertyName,
|
||||||
ContentItem linkTarget) {
|
ContentItem linkTarget,
|
||||||
|
ContentItem sourceObject) {
|
||||||
OID oid = new OID(BASE_DATA_OBJECT_TYPE);
|
OID oid = new OID(BASE_DATA_OBJECT_TYPE);
|
||||||
oid.set(SOURCE_MASTER_ITEM, DomainServiceInterfaceExposer.getDataObject(sourceMasterItem));
|
oid.set(SOURCE_MASTER_ITEM, DomainServiceInterfaceExposer.getDataObject(sourceMasterItem));
|
||||||
oid.set(PROPERTY_NAME, propertyName);
|
oid.set(PROPERTY_NAME, propertyName);
|
||||||
|
|
@ -134,17 +139,21 @@ class PublishedLink extends DomainObject {
|
||||||
if (linkSource instanceof ACSObject) {
|
if (linkSource instanceof ACSObject) {
|
||||||
oid.set(PENDING_SOURCE, DomainServiceInterfaceExposer.getDataObject(linkSource));
|
oid.set(PENDING_SOURCE, DomainServiceInterfaceExposer.getDataObject(linkSource));
|
||||||
} else {
|
} else {
|
||||||
Assert.fail("Cannot set PublishedLink source " + linkSource + "; it is not an " +
|
Assert.fail("Cannot set PublishedLink source " + linkSource + "; it is not an "
|
||||||
"ACSObject");
|
+ "ACSObject");
|
||||||
}
|
}
|
||||||
|
|
||||||
PublishedLink link = null;
|
PublishedLink link = null;
|
||||||
try {
|
try {
|
||||||
link = new PublishedLink(oid);
|
link = new PublishedLink(oid);
|
||||||
} catch (DataObjectNotFoundException e) {
|
} catch (DataObjectNotFoundException e) {
|
||||||
link = new PublishedLink(SessionManager.getSession().create(oid));
|
link = new PublishedLink(SessionManager.getSession().create(oid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sourceObject.getObjectType().getProperty(propertyName).isCollection()) {
|
||||||
|
link.saveLinkAttributes((DataCollection) sourceObject.get(propertyName + "@link"));
|
||||||
|
}
|
||||||
|
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,9 +168,8 @@ class PublishedLink extends DomainObject {
|
||||||
ContentItem getSourceMasterItem() {
|
ContentItem getSourceMasterItem() {
|
||||||
final DataObject item = (DataObject) get(SOURCE_MASTER_ITEM);
|
final DataObject item = (DataObject) get(SOURCE_MASTER_ITEM);
|
||||||
|
|
||||||
return item == null ? null :
|
return item == null ? null
|
||||||
(ContentItem) DomainObjectFactory.newInstance
|
: (ContentItem) DomainObjectFactory.newInstance((DataObject) item);
|
||||||
((DataObject) item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -174,9 +182,8 @@ class PublishedLink extends DomainObject {
|
||||||
// this will need to be refactored if we switch to OIDs
|
// this will need to be refactored if we switch to OIDs
|
||||||
final DataObject item = (DataObject) get(PENDING_SOURCE);
|
final DataObject item = (DataObject) get(PENDING_SOURCE);
|
||||||
|
|
||||||
return item == null ? null :
|
return item == null ? null
|
||||||
DomainObjectFactory.newInstance
|
: DomainObjectFactory.newInstance((DataObject) item);
|
||||||
((DataObject) item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -186,7 +193,7 @@ class PublishedLink extends DomainObject {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
String getPropertyName() {
|
String getPropertyName() {
|
||||||
return (String) get(PROPERTY_NAME);
|
return (String) get(PROPERTY_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -200,9 +207,8 @@ class PublishedLink extends DomainObject {
|
||||||
ContentItem getLinkTarget() {
|
ContentItem getLinkTarget() {
|
||||||
final DataObject item = (DataObject) get(DRAFT_TARGET);
|
final DataObject item = (DataObject) get(DRAFT_TARGET);
|
||||||
|
|
||||||
return item == null ? null :
|
return item == null ? null
|
||||||
(ContentItem) DomainObjectFactory.newInstance
|
: (ContentItem) DomainObjectFactory.newInstance((DataObject) item);
|
||||||
((DataObject) item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -246,15 +252,17 @@ class PublishedLink extends DomainObject {
|
||||||
// will change w/ OID references
|
// will change w/ OID references
|
||||||
DataObject master = (DataObject) coll.get(SOURCE_MASTER_ITEM);
|
DataObject master = (DataObject) coll.get(SOURCE_MASTER_ITEM);
|
||||||
DataObject src = (DataObject) coll.get(PENDING_SOURCE);
|
DataObject src = (DataObject) coll.get(PENDING_SOURCE);
|
||||||
src.specialize((String)src.get(ACSObject.OBJECT_TYPE));
|
src.specialize((String) src.get(ACSObject.OBJECT_TYPE));
|
||||||
String propertyName = (String) coll.get(PROPERTY_NAME);
|
String propertyName = (String) coll.get(PROPERTY_NAME);
|
||||||
|
byte[] linkAttributes = (byte[]) coll.get(LINK_ATTRIBUTES);
|
||||||
|
|
||||||
Assert.exists(src, DataObject.class);
|
Assert.exists(src, DataObject.class);
|
||||||
Assert.exists(propertyName, String.class);
|
Assert.exists(propertyName, String.class);
|
||||||
|
|
||||||
DataObject target = null;
|
DataObject target = null;
|
||||||
DataObject draftTarget = (DataObject) coll.get(DRAFT_TARGET);
|
DataObject draftTarget = (DataObject) coll.get(DRAFT_TARGET);
|
||||||
DataAssociationCursor targetVersions =
|
DataAssociationCursor targetVersions =
|
||||||
((DataAssociation) draftTarget.get(ContentItem.VERSIONS)).cursor();
|
((DataAssociation) draftTarget.get(ContentItem.VERSIONS)).cursor();
|
||||||
targetVersions.addEqualsFilter(ContentItem.VERSION, ContentItem.LIVE);
|
targetVersions.addEqualsFilter(ContentItem.VERSION, ContentItem.LIVE);
|
||||||
if (targetVersions.next()) {
|
if (targetVersions.next()) {
|
||||||
target = targetVersions.getDataObject();
|
target = targetVersions.getDataObject();
|
||||||
|
|
@ -265,10 +273,10 @@ class PublishedLink extends DomainObject {
|
||||||
Property prop = ot.getProperty(propertyName);
|
Property prop = ot.getProperty(propertyName);
|
||||||
Assert.exists(prop, propertyName + " for type " + ot.getQualifiedName() + ", ID: " + src.get("id"));
|
Assert.exists(prop, propertyName + " for type " + ot.getQualifiedName() + ", ID: " + src.get("id"));
|
||||||
if (prop.isCollection()) {
|
if (prop.isCollection()) {
|
||||||
DataAssociation da = (DataAssociation) src.get(propertyName);
|
DataAssociation da = (DataAssociation) src.get(propertyName);
|
||||||
da.add(target);
|
setLinkAttributesForLiveLink(da.add(target), linkAttributes);
|
||||||
} else {
|
} else {
|
||||||
src.set(propertyName,target);
|
src.set(propertyName, target);
|
||||||
}
|
}
|
||||||
if (itemsToRefresh != null && master != null) {
|
if (itemsToRefresh != null && master != null) {
|
||||||
itemsToRefresh.add(master.getOID());
|
itemsToRefresh.add(master.getOID());
|
||||||
|
|
@ -309,4 +317,76 @@ class PublishedLink extends DomainObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveLinkAttributes(DataCollection coll) {
|
||||||
|
|
||||||
|
if (coll.next()) {
|
||||||
|
|
||||||
|
DataObject linkObj = coll.getDataObject();
|
||||||
|
|
||||||
|
Iterator properties = linkObj.getObjectType().getDeclaredProperties();
|
||||||
|
HashMap<String, Object> linkAttributes = new HashMap();
|
||||||
|
|
||||||
|
while (properties.hasNext()) {
|
||||||
|
|
||||||
|
Property prop = (Property) properties.next();
|
||||||
|
String key = prop.getName();
|
||||||
|
|
||||||
|
// Teste Property: Es darf kein Key und muß ein simples Attribute sein
|
||||||
|
if (prop.isAttribute() && !prop.isKeyProperty()) {
|
||||||
|
|
||||||
|
Object value = linkObj.get(key);
|
||||||
|
linkAttributes.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linkAttributes.size() > 0) {
|
||||||
|
ByteArrayOutputStream data = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
ObjectOutputStream out = new ObjectOutputStream(data);
|
||||||
|
out.writeObject(linkAttributes);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
|
||||||
|
set(LINK_ATTRIBUTES, data.toByteArray());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setLinkAttributesForLiveLink(DataObject link, byte[] linkAttributes) {
|
||||||
|
|
||||||
|
if (linkAttributes != null) {
|
||||||
|
ByteArrayInputStream data = null;
|
||||||
|
ObjectInputStream in = null;
|
||||||
|
HashMap<String, Object> attributes = null;
|
||||||
|
|
||||||
|
data = new ByteArrayInputStream(linkAttributes);
|
||||||
|
|
||||||
|
try {
|
||||||
|
in = new ObjectInputStream(data);
|
||||||
|
try {
|
||||||
|
attributes = (HashMap<String, Object>) in.readObject();
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
s_log.error("Class HashMap not found? WTF?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
s_log.error("Can't read HashMap from database");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributes != null) {
|
||||||
|
Iterator keys = attributes.keySet().iterator();
|
||||||
|
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String propertyName = (String) keys.next();
|
||||||
|
Object value = (Object) attributes.get(propertyName);
|
||||||
|
|
||||||
|
if (link.getObjectType().hasDeclaredProperty(propertyName) && link.getSession() != null) {
|
||||||
|
link.set(propertyName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,15 @@ import com.arsdigita.persistence.OID;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Relation Attribute
|
||||||
|
*
|
||||||
|
* The purpose of this class is to provide a database driven enumeration of
|
||||||
|
* attributes. It can be used to create enumerated selects for content type
|
||||||
|
* or association attributes, which can be modified during runtime.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* For the moment, it will handle the translation by itself. This may be modified
|
||||||
|
* to use the GlobalizationService, when it is database driven.
|
||||||
*
|
*
|
||||||
* @author quasi
|
* @author quasi
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ class VersionCopier extends ObjectCopier {
|
||||||
* @param item the item to be copied
|
* @param item the item to be copied
|
||||||
* @return a copy of the item
|
* @return a copy of the item
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public ContentItem copyItem(final ContentItem item) {
|
public ContentItem copyItem(final ContentItem item) {
|
||||||
m_trace.enter("copyItem", item);
|
m_trace.enter("copyItem", item);
|
||||||
|
|
||||||
|
|
@ -118,6 +119,7 @@ class VersionCopier extends ObjectCopier {
|
||||||
/**
|
/**
|
||||||
* This copier is used to create published copies of items
|
* This copier is used to create published copies of items
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public int getCopyType() {
|
public int getCopyType() {
|
||||||
return ItemCopier.VERSION_COPY;
|
return ItemCopier.VERSION_COPY;
|
||||||
}
|
}
|
||||||
|
|
@ -129,6 +131,7 @@ class VersionCopier extends ObjectCopier {
|
||||||
*
|
*
|
||||||
* @param source the <code>DomainObject</code> from which to copy
|
* @param source the <code>DomainObject</code> from which to copy
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public DomainObject copy(final DomainObject object) {
|
public DomainObject copy(final DomainObject object) {
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
m_traversedComponents.add(object);
|
m_traversedComponents.add(object);
|
||||||
|
|
@ -168,6 +171,7 @@ class VersionCopier extends ObjectCopier {
|
||||||
* @param prop the <code>Property</code> currently under
|
* @param prop the <code>Property</code> currently under
|
||||||
* consideration
|
* consideration
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
protected DomainObject copy(final DomainObject source,
|
protected DomainObject copy(final DomainObject source,
|
||||||
final DomainObject target,
|
final DomainObject target,
|
||||||
final DomainObject object,
|
final DomainObject object,
|
||||||
|
|
@ -214,8 +218,7 @@ class VersionCopier extends ObjectCopier {
|
||||||
s_log.debug("The property is not a component; creating " +
|
s_log.debug("The property is not a component; creating " +
|
||||||
"PublishedLink for the item");
|
"PublishedLink for the item");
|
||||||
|
|
||||||
PublishedLink.create((ContentItem) getCopy(m_topLevelSourceOID), target, prop.getName(), item);
|
PublishedLink.create((ContentItem) getCopy(m_topLevelSourceOID), target, prop.getName(), item, (ContentItem) source);
|
||||||
|
|
||||||
m_trace.exit("copy", null);
|
m_trace.exit("copy", null);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue