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-94f89814c4df
master
quasi 2010-10-28 12:23:48 +00:00
parent afd350c7b9
commit 53e63abbc3
4 changed files with 126 additions and 36 deletions

View File

@ -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 = composite ContentItem[1..1] draftTarget = join cms_published_links.draft_target to cms_items.item_id;
join cms_published_links.draft_target to cms_items.item_id; Blob[0..1] linkAttributes = cms_published_links.link_attributes BLOB;
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);
} }

View File

@ -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;
} }
@ -124,7 +128,8 @@ class PublishedLink extends DomainObject {
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,8 +139,8 @@ 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;
@ -145,6 +150,10 @@ class PublishedLink extends DomainObject {
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);
} }
/** /**
@ -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,8 +252,10 @@ 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);
@ -266,9 +274,9 @@ class PublishedLink extends DomainObject {
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);
}
}
}
}
}
} }

View File

@ -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
*/ */

View File

@ -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;