diff --git a/ccm-cms/src/com/arsdigita/cms/ContentItem.java b/ccm-cms/src/com/arsdigita/cms/ContentItem.java index 964df7614..09e9d4cb6 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentItem.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentItem.java @@ -203,10 +203,12 @@ import java.util.Set; public class ContentItem extends VersionedACSObject implements CustomCopy { private static final Logger s_log = Logger.getLogger(ContentItem.class); - private static final Logger s_logDenorm = Logger.getLogger(ContentItem.class.getName() + ".Denorm"); + private static final Logger s_logDenorm = + Logger.getLogger(ContentItem.class.getName() + + ".Denorm"); private static final String MODEL = "com.arsdigita.cms"; private static final String QUERY_PENDING_ITEMS = - MODEL + ".getPendingSortedByLifecycle"; + MODEL + ".getPendingSortedByLifecycle"; public static final String BASE_DATA_OBJECT_TYPE = MODEL + ".ContentItem"; /** * A state marking the draft or master item corresponding to a @@ -234,7 +236,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { public static final String VERSIONS = "slaveVersions"; public static final String CONTENT_SECTION = "section"; private static final String PUBLISH_LISTENER_CLASS = - PublishLifecycleListener.class.getName(); + PublishLifecycleListener.class.getName(); private VersionCache m_pending; private VersionCache m_live; private boolean m_wasNew; @@ -302,19 +304,20 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { } } private static DomainObjectObserver s_parentObs = - new AbstractDomainObjectObserver() { + new AbstractDomainObjectObserver() { - public void set(DomainObject dobj, String name, + public void set(DomainObject dobj, String name, Object old, Object newVal) { - if (PARENT.equals(name)) { - ContentItem ci = (ContentItem) dobj; + if (PARENT.equals(name)) { + ContentItem ci = (ContentItem) dobj; - if (newVal != null) { - PermissionService.setContext(ci.getOID(), ((DataObject) newVal).getOID()); - } - } + if (newVal != null) { + PermissionService.setContext(ci.getOID(), + ((DataObject) newVal).getOID()); } - }; + } + } + }; /** * Called from the base class (DomainObject) @@ -341,7 +344,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (isNew()) { s_log.debug(this + " is being newly created; " - + "marking it as a draft version"); + + "marking it as a draft version"); m_wasNew = true; @@ -351,7 +354,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { try { final ContentType type = - ContentType.findByAssociatedObjectType(getSpecificObjectType()); + ContentType.findByAssociatedObjectType( + getSpecificObjectType()); if (s_log.isDebugEnabled()) { s_log.debug("Set content type for " + this + " to " + type); @@ -406,12 +410,12 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { * @param propertyName * @param dobj * @return - */ + */ @Override public DataObject add(String propertyName, DomainObject dobj) { return super.add(propertyName, dobj); } - + /** * Public remove for use by metadata forms * @@ -422,11 +426,11 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { public void remove(String propertyName, DomainObject dobj) { super.remove(propertyName, dobj); } - + /** * For new content items, sets the associated content type if it * has not been already set. - */ + */ @Override protected void beforeSave() { m_wasNew = isNew(); @@ -442,10 +446,10 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { } /* - + removed cg - object observer sets context based on parent whenever parent is updated - + protected void afterSave() { super.afterSave(); s_log.info("******After Save of object " + getOID()); @@ -478,11 +482,11 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { setContentSection(((ContentItem) parent).getContentSection()); } else { s_log.debug("The item's parent is not a folder; I am " - + "not setting the default content section"); + + "not setting the default content section"); } } else { s_log.debug("The item's version is null or it is not draft; " - + "doing nothing"); + + "doing nothing"); } } @@ -522,7 +526,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { * Get the parent object. */ public ACSObject getParent() { - return (ACSObject) DomainObjectFactory.newInstance((DataObject) get(PARENT)); + return (ACSObject) DomainObjectFactory.newInstance((DataObject) get( + PARENT)); } /** @@ -542,7 +547,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { */ public final ItemCollection getChildren() { final DataAssociationCursor cursor = - ((DataAssociation) super.get(CHILDREN)).cursor(); + ((DataAssociation) super.get(CHILDREN)). + cursor(); return new ItemCollection(cursor); } @@ -598,7 +604,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { * @return The content section to which this item belongs */ public ContentSection getContentSection() { - return (ContentSection) DomainObjectFactory.newInstance((DataObject) get(CONTENT_SECTION)); + return (ContentSection) DomainObjectFactory.newInstance((DataObject) get( + CONTENT_SECTION)); } /** @@ -694,7 +701,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { * @return the items on the path to the root folder. */ public ItemCollection getPathInfo(boolean includeSelf) { - DataCollection collection = SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE); + DataCollection collection = SessionManager.getSession().retrieve( + BASE_DATA_OBJECT_TYPE); String ids = (String) get(ANCESTORS); if (ids == null) { @@ -858,7 +866,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { DataQuery versions = getSession().retrieveQuery(QUERY_PENDING_ITEMS); versions.setParameter("itemID", getDraftVersion().getID()); - return new ItemCollection(new DataQueryDataCollectionAdapter(versions, "item")); + return new ItemCollection(new DataQueryDataCollectionAdapter(versions, + "item")); } /** @@ -934,13 +943,15 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { s_log.debug("m_live miss"); final DataAssociationCursor versions = - ((DataAssociation) get(VERSIONS)).cursor(); + ((DataAssociation) get(VERSIONS)).cursor(); versions.addEqualsFilter(VERSION, LIVE); try { if (versions.next()) { - ContentItem item = (ContentItem) DomainObjectFactory.newInstance(versions.getDataObject()); + ContentItem item = + (ContentItem) DomainObjectFactory.newInstance(versions. + getDataObject()); return m_live.set(item); } return m_live.set(null); @@ -1068,18 +1079,18 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { public void setLive(final ContentItem version) { if (s_log.isDebugEnabled()) { s_log.debug("Setting item " + this + " live with version " - + version); + + version); } if (Assert.isEnabled()) { Assert.isTrue(version == null || LIVE.equals(version.getVersion()), - "Item version " + version + " must be null or " - + "the live version"); + "Item version " + version + " must be null or " + + "the live version"); } if (isLive()) { s_log.debug("The item is already live; getting the current " - + "live version"); + + "live version"); final ContentItem oldVersion = getLiveVersion(); @@ -1096,7 +1107,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { // XXX We don't need to use a custom query here // anymore. final DataQuery items = - SessionManager.getSession().retrieveQuery("com.arsdigita.cms.getLiveItemsWithSameParent"); + SessionManager.getSession().retrieveQuery( + "com.arsdigita.cms.getLiveItemsWithSameParent"); items.addNotEqualsFilter("id", oldVersion.getID()); items.setParameter("itemId", oldVersion.getID()); @@ -1109,7 +1121,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (s_log.isDebugEnabled()) { s_log.debug(oldVersion + " is the last child of " - + parent); + + parent); } } @@ -1131,14 +1143,14 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (parent instanceof ContentBundle || parent instanceof Folder) { if (s_log.isDebugEnabled()) { s_log.debug("Parent of " + oldVersion + " is " + parent - + "; unpublishing the parent"); + + "; unpublishing the parent"); } ((ContentItem) parent).setLive(null); } s_log.debug("Setting the live version association to null and " - + "saving"); + + "saving"); setLiveVersion(null); @@ -1147,7 +1159,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (version != null) { s_log.debug("The new version is not null; setting the live " - + "version association"); + + "version association"); setLiveVersion(version); @@ -1174,15 +1186,15 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { * @return the new pending version */ public ContentItem publish(final LifecycleDefinition cycleDef, - final Date startDate) { + final Date startDate) { applyTag("Published"); Versions.suspendVersioning(); if (s_log.isDebugEnabled()) { s_log.debug("Publishing item " + this + " with lifecycle " - + "definition " + cycleDef + " and start date " - + startDate); + + "definition " + cycleDef + " and start date " + + startDate); } /* amended Chris Gilbert * @@ -1196,7 +1208,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (listener == null) { listener = getPublishListenerClassName(); } - final Lifecycle cycle = cycleDef.createFullLifecycle(startDate, listener); + final Lifecycle cycle = + cycleDef.createFullLifecycle(startDate, listener); if (s_log.isDebugEnabled()) { s_log.debug("Instantiated lifecycle " + cycle); @@ -1212,15 +1225,16 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (Assert.isEnabled()) { Assert.exists(pending, ContentItem.class); Assert.isTrue(PENDING.equals(pending.getVersion()) - || LIVE.equals(pending.getVersion()), - "The new pending item must be pending or live; " - + "instead it is " + pending.getVersion()); + || LIVE.equals(pending.getVersion()), + "The new pending item must be pending or live; " + + "instead it is " + pending.getVersion()); } return pending; } public String getPublishListenerClassName() { - String className = ContentSection.getConfig().getPublishLifecycleListenerClass(); + String className = ContentSection.getConfig(). + getPublishLifecycleListenerClass(); if (className != null && !"".equals(className)) { return className; } else { @@ -1243,8 +1257,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (isLive()) { if (s_log.isDebugEnabled()) { s_log.debug("The item is currently live; removing the " - + "lifecycle of the public version, " - + getPublicVersion()); + + "lifecycle of the public version, " + + getPublicVersion()); } removeLifecycle(getPublicVersion()); @@ -1319,7 +1333,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (lifecycle == null) { if (s_log.isDebugEnabled()) { s_log.debug("The item has no lifecycle; checking if the " - + "public version has a lifecycle"); + + "public version has a lifecycle"); } final ContentItem pub = getPublicVersion(); @@ -1333,7 +1347,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (s_log.isDebugEnabled()) { s_log.debug("The public version has a lifecycle; " - + "returning " + cyclelife); + + "returning " + cyclelife); } return cyclelife; @@ -1382,7 +1396,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { if (s_log.isDebugEnabled()) { s_log.debug("Removing lifecycle instance from item " - + itemToRemove); + + itemToRemove); } LifecycleService.removeLifecycle(itemToRemove); @@ -1434,11 +1448,12 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { } - Category root = Category.getRootForObject(getContentSection(), useContext); + Category root = Category.getRootForObject(getContentSection(), + useContext); if (null == root) { s_log.warn("No root category for " - + getContentSection().getOID().toString() - + " with context " + useContext); + + getContentSection().getOID().toString() + + " with context " + useContext); return Collections.EMPTY_LIST.iterator(); } @@ -1533,6 +1548,10 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { public ContentItem copy() { return copy(null, false); } + + public ContentItem copy(String lang) { + return copy(null, false, lang); + } /** * Recursively copy this item, creating a clone. @@ -1548,7 +1567,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { * @return the new copy of the item * @see #copyServicesFrom(ContentItem) */ - final public ContentItem copy(final ContentItem newParent, final boolean copyServices) { + final public ContentItem copy(final ContentItem newParent, + final boolean copyServices) { ContentItem newItem = makeCopy(); if (newParent != null) { newItem.setParent(newParent); @@ -1558,6 +1578,21 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { } return newItem; } + + final public ContentItem copy(final ContentItem newParent, + final boolean copyServices, + final String lang) { + ContentItem newItem = makeCopy(lang); + if (newParent != null) { + newItem.setParent(newParent); + } + if (copyServices) { + newItem.copyServicesFrom(this); + } + return newItem; + } + + /** * Performs the actual mechanics of copying a content item. @@ -1579,6 +1614,29 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { return newItem; } + /** + * Variant of {@link ACSObject#makeCopy} which allows to pass the (further) + * language of the copy. + * + * @param language + * @return + */ + protected ContentItem makeCopy(String language) { + if (s_log.isDebugEnabled()) { + s_log.debug("Copy taking place", new Throwable("trace")); + } + + LanguageAwareObjectCopier copier = new LanguageAwareObjectCopier( + language); + + final ContentItem newItem = copier.copyItem(this); + // Doesn't seem like I should have to do this, but what the hell + newItem.setContentSection(getContentSection()); + newItem.save(); + + return newItem; + } + /** * Transfer services, such as categories, * from the passed-in item to this item. This method should be @@ -1653,7 +1711,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { setLive(pending); ContentBundle draftBundle = getBundle(); ContentBundle liveBundle = pending.getBundle(); - if (draftBundle != null && liveBundle != null && !liveBundle.isLiveVersion()) { + if (draftBundle != null && liveBundle != null && !liveBundle. + isLiveVersion()) { draftBundle.promotePendingVersion(liveBundle); } @@ -1669,7 +1728,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { */ protected void setVersionRecursively(final String version) { s_log.debug("Recursively updating the version attribute of the " - + "item"); + + "item"); new VersionUpdater(version).updateItemVersion(this); } @@ -1702,9 +1761,10 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { * @deprecated use {@link #copyProperty(CustomCopy, Property, ItemCopier)} instead */ protected final boolean copyProperty(final ContentItem source, - final String attribute, - final ItemCopier copier) { - throw new UnsupportedOperationException("use copyProperty(CustomCopy, Property, ItemCopier) for copying"); + final String attribute, + final ItemCopier copier) { + throw new UnsupportedOperationException( + "use copyProperty(CustomCopy, Property, ItemCopier) for copying"); } /** @@ -1793,8 +1853,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { * to copy the property. */ public boolean copyProperty(final CustomCopy source, - final Property property, - final ItemCopier copier) { + final Property property, + final ItemCopier copier) { String attribute = property.getName(); if (CHILDREN.equals(attribute)) { return true; @@ -1822,26 +1882,29 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { // If live Bundle already exists, recategorize. if (PARENT.equals(attribute)) { ACSObject parent = ((ContentItem) source).getParent(); - if (parent != null && copier.getCopyType() == ItemCopier.VERSION_COPY) { + if (parent != null && copier.getCopyType() + == ItemCopier.VERSION_COPY) { if (parent instanceof ContentBundle) { ContentBundle bundle = (ContentBundle) parent; - ContentBundle liveBundle = (ContentBundle) bundle.getPublicVersion(); + ContentBundle liveBundle = (ContentBundle) bundle. + getPublicVersion(); if (liveBundle == null) { - liveBundle = (ContentBundle) bundle.createPendingVersion(null); + liveBundle = + (ContentBundle) bundle.createPendingVersion(null); } else { Set liveCatSet = new HashSet(); Set draftCatSet = new HashSet(); CategoryCollection liveCategories = - liveBundle.getCategoryCollection(); + liveBundle.getCategoryCollection(); while (liveCategories.next()) { liveCatSet.add(liveCategories.getCategory()); } liveCategories.close(); CategoryCollection draftCategories = - bundle.getCategoryCollection(); + bundle.getCategoryCollection(); while (draftCategories.next()) { draftCatSet.add(draftCategories.getCategory()); } @@ -1854,7 +1917,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { Iterator removeIter = catsToRemove.iterator(); while (removeIter.hasNext()) { - liveBundle.removeCategory((Category) removeIter.next()); + liveBundle.removeCategory( + (Category) removeIter.next()); } Iterator addIter = catsToAdd.iterator(); while (addIter.hasNext()) { @@ -1932,7 +1996,8 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { // slp.getLocale() try { - locale = Locale.fromJavaLocale(new java.util.Locale(getLanguage(), "")); + locale = Locale.fromJavaLocale(new java.util.Locale(getLanguage(), + "")); } catch (GlobalizationException e) { s_log.warn("GlobalizationException thrown in getLocale()", e); throw new UncheckedWrapperException(e.getMessage()); @@ -2024,20 +2089,26 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { super.beforeDelete(); // remove Link associations to this - DataCollection dc = SessionManager.getSession().retrieve(Link.BASE_DATA_OBJECT_TYPE); + DataCollection dc = SessionManager.getSession().retrieve( + Link.BASE_DATA_OBJECT_TYPE); dc.addEqualsFilter(Link.TARGET_ITEM + "." + ACSObject.ID, - getID()); + getID()); while (dc.next()) { - Link link = (Link) DomainObjectFactory.newInstance(dc.getDataObject()); + Link link = (Link) DomainObjectFactory.newInstance( + dc.getDataObject()); link.setTargetItem(null); } // remove ContentGroup associations to this - dc = SessionManager.getSession().retrieve(ContentGroupAssociation.BASE_DATA_OBJECT_TYPE); - dc.addEqualsFilter(ContentGroupAssociation.CONTENT_ITEM + "." + ACSObject.ID, - getID()); + dc = SessionManager.getSession().retrieve( + ContentGroupAssociation.BASE_DATA_OBJECT_TYPE); + dc.addEqualsFilter(ContentGroupAssociation.CONTENT_ITEM + "." + + ACSObject.ID, + getID()); while (dc.next()) { - ContentGroupAssociation groupAssoc = (ContentGroupAssociation) DomainObjectFactory.newInstance(dc.getDataObject()); + ContentGroupAssociation groupAssoc = + (ContentGroupAssociation) DomainObjectFactory. + newInstance(dc.getDataObject()); groupAssoc.setContentItem(null); } } @@ -2110,5 +2181,4 @@ public class ContentItem extends VersionedACSObject implements CustomCopy { public List getExtraXMLGenerators() { return extraXMLGenerators; } - } diff --git a/ccm-cms/src/com/arsdigita/cms/DomainCopier.java b/ccm-cms/src/com/arsdigita/cms/DomainCopier.java index b7b8ab15e..d06109855 100755 --- a/ccm-cms/src/com/arsdigita/cms/DomainCopier.java +++ b/ccm-cms/src/com/arsdigita/cms/DomainCopier.java @@ -47,10 +47,9 @@ import java.util.Iterator; class DomainCopier extends DomainService { private static Logger s_log = Logger.getLogger(DomainCopier.class); - // A map of OID => DomainObject private final HashMap m_copied; - private final TraversedSet m_traversed; + protected final TraversedSet m_traversed; final Tracer m_trace; /** @@ -69,7 +68,7 @@ class DomainCopier extends DomainService { * * @param source the DomainObject from which to copy */ - public DomainObject copy(final DomainObject source) { + public DomainObject copy(final DomainObject source) { m_trace.enter("copy", source); final OID sourceOID = source.getOID(); @@ -90,15 +89,15 @@ class DomainCopier extends DomainService { if (source instanceof ACSObject) { final String type = - ((ACSObject) source).getSpecificObjectType(); - - target = (DomainObject)Classes.newInstance( - clacc, - new Class[] { String.class }, - new Object[] { type }); + ((ACSObject) source).getSpecificObjectType(); + + target = (DomainObject) Classes.newInstance( + clacc, + new Class[]{String.class}, + new Object[]{type}); } else { - Assert.fail("Cannot copy " + source + "; it is not an " + - "ACSObject"); + Assert.fail("Cannot copy " + source + "; it is not an " + + "ACSObject"); // XXX Contrary to this assertion, it is reasonable to // copy domain objects, and this code should support // it. @@ -129,59 +128,59 @@ class DomainCopier extends DomainService { } protected void copyData(final DomainObject source, DomainObject target) { - final ObjectType type = source.getObjectType(); + final ObjectType type = source.getObjectType(); - if (s_log.isDebugEnabled()) { - s_log.debug("Using object type " + type.getName()); + if (s_log.isDebugEnabled()) { + s_log.debug("Using object type " + type.getName()); + } + + // XXX This is what I would like to do: + // + //final Iterator iter = type.getProperties(); + // + //while (iter.hasNext()) { + // copyProperty(source, target, (Property) iter.next()); + //} + + // But the beforeSave-on-flush behavior makes it so I have + // to do this instead: + + Iterator iter = type.getProperties(); + final ArrayList attributes = new ArrayList(); + final ArrayList roles = new ArrayList(); + final ArrayList collections = new ArrayList(); + + while (iter.hasNext()) { + final Property prop = (Property) iter.next(); + + if (prop.isAttribute()) { + attributes.add(prop); + } else if (prop.isCollection()) { + collections.add(prop); + } else { + roles.add(prop); } + } - // XXX This is what I would like to do: - // - //final Iterator iter = type.getProperties(); - // - //while (iter.hasNext()) { - // copyProperty(source, target, (Property) iter.next()); - //} + iter = attributes.iterator(); - // But the beforeSave-on-flush behavior makes it so I have - // to do this instead: + while (iter.hasNext()) { + copyProperty(source, target, (Property) iter.next()); + } - Iterator iter = type.getProperties(); - final ArrayList attributes = new ArrayList(); - final ArrayList roles = new ArrayList(); - final ArrayList collections = new ArrayList(); + iter = roles.iterator(); - while (iter.hasNext()) { - final Property prop = (Property) iter.next(); + while (iter.hasNext()) { + copyProperty(source, target, (Property) iter.next()); + } - if (prop.isAttribute()) { - attributes.add(prop); - } else if (prop.isCollection()) { - collections.add(prop); - } else { - roles.add(prop); - } - } + iter = collections.iterator(); - iter = attributes.iterator(); + while (iter.hasNext()) { + copyProperty(source, target, (Property) iter.next()); + } - while (iter.hasNext()) { - copyProperty(source, target, (Property) iter.next()); - } - iter = roles.iterator(); - - while (iter.hasNext()) { - copyProperty(source, target, (Property) iter.next()); - } - - iter = collections.iterator(); - - while (iter.hasNext()) { - copyProperty(source, target, (Property) iter.next()); - } - - } /** @@ -211,8 +210,8 @@ class DomainCopier extends DomainService { } if (prop.isKeyProperty()) { - s_log.debug("The property is one of the key properties; " + - "skipping it"); + s_log.debug("The property is one of the key properties; " + + "skipping it"); } else { s_log.debug("Copying is enabled; proceeding"); @@ -281,8 +280,8 @@ class DomainCopier extends DomainService { final String name = prop.getName(); if (m_traversed.contains(source, prop)) { - s_log.debug("The role belongs to a link that has " + - "already been traversed; skipping it"); + s_log.debug("The role belongs to a link that has " + + "already been traversed; skipping it"); } else { // This marks the forward link traversed. Further down, // in this method and in copyCollection, we mark the @@ -363,12 +362,13 @@ class DomainCopier extends DomainService { m_traversed.add(selem, reverse); final DomainObject telem = copy(source, target, selem, prop); + DataObject tgtLink = null; // removing this assert since copy will return null in the // case of deferred association creation in VersionCopier //Assert.exists(telem, DomainObject.class); - + if (telem != null) { tgtLink = add(target, name, telem); } @@ -410,8 +410,7 @@ class DomainCopier extends DomainService { if (prop.isComponent()) { if (s_log.isDebugEnabled()) { - s_log.debug("The property is a component; " + - "copying by value"); + s_log.debug("The property is a component; " + "copying by value"); } final DomainObject copy = copy(object); @@ -420,8 +419,8 @@ class DomainCopier extends DomainService { return copy; } else { - s_log.debug("The property is not a component; " + - "copying by reference"); + s_log.debug("The property is not a component; " + + "copying by reference"); m_trace.exit("copy", object); @@ -442,10 +441,8 @@ class DomainCopier extends DomainService { return (DomainObject) m_copied.get(oid); } - // Utility methods and classes - - private DomainObject domain(final DataObject data) { + protected DomainObject domain(final DataObject data) { Assert.exists(data, DataObject.class); final DomainObject domain = DomainObjectFactory.newInstance(data); @@ -455,7 +452,8 @@ class DomainCopier extends DomainService { return domain; } - private static class TraversedSet extends HashSet { + protected static class TraversedSet extends HashSet { + void add(final DomainObject object, final Property prop) { Assert.exists(object, DomainObject.class); @@ -472,14 +470,15 @@ class DomainCopier extends DomainService { return contains(object.getOID() + "." + prop.getName()); } } - private final class WrapperDomainObject extends DomainObject{ + + protected final class WrapperDomainObject extends DomainObject { + public WrapperDomainObject(DataObject dobj) { super(dobj); } - + public WrapperDomainObject(OID oid) { super(oid); } - } } diff --git a/ccm-cms/src/com/arsdigita/cms/LanguageAwareObjectCopier.java b/ccm-cms/src/com/arsdigita/cms/LanguageAwareObjectCopier.java new file mode 100644 index 000000000..924941b20 --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/LanguageAwareObjectCopier.java @@ -0,0 +1,76 @@ +package com.arsdigita.cms; + +import com.arsdigita.domain.DomainObject; +import com.arsdigita.persistence.DataAssociation; +import com.arsdigita.persistence.DataAssociationCursor; +import com.arsdigita.persistence.DataObject; +import com.arsdigita.persistence.metadata.Property; +import org.apache.log4j.Logger; + +/** + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class LanguageAwareObjectCopier extends ObjectCopier { + + private static final Logger logger = + Logger.getLogger(LanguageAwareObjectCopier.class); + private String language; + + public LanguageAwareObjectCopier(String language) { + super(); + this.language = language; + } + + @Override + protected void copyCollection(final DomainObject source, + final DomainObject target, + final Property prop) { + if (source instanceof ContentPage) { + + if (logger.isDebugEnabled()) { + logger.debug("Copying collection " + prop); + } + + final String name = prop.getName(); + + final DataAssociation sass = (DataAssociation) get(source, name); + final DataAssociationCursor scursor = sass.cursor(); + final Property reverse = prop.getAssociatedProperty(); + + while (scursor.next()) { + final DomainObject selem = domain(scursor.getDataObject()); + + m_traversed.add(selem, reverse); + + DomainObject telem = copy(source, target, selem, prop); + if (telem instanceof ContentPage) { + ContentPage tpage = (ContentPage) telem; + telem = tpage.getContentBundle().getInstance(language); + } + + DataObject tgtLink = null; + + // removing this assert since copy will return null in the + // case of deferred association creation in VersionCopier + //Assert.exists(telem, DomainObject.class); + + if (telem != null) { + tgtLink = add(target, name, telem); + } + if (tgtLink != null) { + // Copy link attributes as well + copyData(new WrapperDomainObject(scursor.getLink()), + new WrapperDomainObject(tgtLink)); + } + + } + + } else { + //Use old behaviour + super.copyCollection(source, target, prop); + } + + } +} diff --git a/ccm-cms/src/com/arsdigita/cms/ui/item/ItemLanguages.java b/ccm-cms/src/com/arsdigita/cms/ui/item/ItemLanguages.java index 5ae4634e6..b61d3ea1f 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/item/ItemLanguages.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/item/ItemLanguages.java @@ -156,7 +156,7 @@ public class ItemLanguages extends LayoutPanel { ContentType type = item.getContentType(); - item = (ContentPage) item.copy(); + item = (ContentPage) item.copy(lang); item.setLanguage(lang); item.setName(name); diff --git a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciDepartmentOrganizationForm.java b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciDepartmentOrganizationForm.java index bcef894e5..7226471c3 100644 --- a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciDepartmentOrganizationForm.java +++ b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciDepartmentOrganizationForm.java @@ -77,9 +77,31 @@ public class SciDepartmentOrganizationForm getSelectedObject(state); if (this.getSaveCancelSection().getSaveButton().isSelected(state)) { - department.setOrganization((SciOrganization) data.get(ITEM_SEARCH)); + SciOrganization orga = (SciOrganization) data.get(ITEM_SEARCH); + + orga = (SciOrganization) orga.getContentBundle().getInstance(department.getLanguage()); + + department.setOrganization(orga); + //department.setOrganization((SciOrganization) data.get(ITEM_SEARCH)); + } + + init(fse); + } - init(fse); + @Override + public void validate(FormSectionEvent fse) throws FormProcessException { + final PageState state = fse.getPageState(); + final FormData data = fse.getFormData(); + + SciDepartment department = (SciDepartment) getItemSelectionModel(). + getSelectedObject(state); + + SciOrganization orga = (SciOrganization) data.get(ITEM_SEARCH); + + if (!(orga.getContentBundle().hasInstance(department.getLanguage()))) { + data.addError( + SciOrganizationGlobalizationUtil.globalize( + "sciorganization.ui.department.organization.add.no_suitable_language_variant")); } } } diff --git a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciDepartmentOrganizationSheet.java b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciDepartmentOrganizationSheet.java index 06c85980c..6f141fe20 100644 --- a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciDepartmentOrganizationSheet.java +++ b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciDepartmentOrganizationSheet.java @@ -22,6 +22,7 @@ package com.arsdigita.cms.contenttypes.ui; import com.arsdigita.bebop.Component; import com.arsdigita.bebop.ControlLink; import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.Link; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.Table; import com.arsdigita.bebop.event.TableActionEvent; @@ -31,12 +32,19 @@ import com.arsdigita.bebop.table.TableColumn; import com.arsdigita.bebop.table.TableColumnModel; import com.arsdigita.bebop.table.TableModel; import com.arsdigita.bebop.table.TableModelBuilder; +import com.arsdigita.cms.CMS; +import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.SecurityManager; import com.arsdigita.cms.contenttypes.SciDepartment; import com.arsdigita.cms.contenttypes.SciOrganization; +import com.arsdigita.cms.dispatcher.ItemResolver; import com.arsdigita.cms.dispatcher.Utilities; +import com.arsdigita.dispatcher.ObjectNotFoundException; +import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.util.LockableImpl; +import java.math.BigDecimal; +import org.apache.log4j.Logger; /** * Sheet for showing the superior organization of a SciDepartment. @@ -49,6 +57,9 @@ public class SciDepartmentOrganizationSheet extends Table implements TableActionListener { + private static final Logger logger = + Logger.getLogger( + SciDepartmentOrganizationSheet.class); private final String TABLE_COL_EDIT = "table_col_edit"; private final String TABLE_COL_DEL = "table_col_del"; private ItemSelectionModel m_itemModel; @@ -169,8 +180,57 @@ public class SciDepartmentOrganizationSheet Object key, int row, int column) { - Label label = new Label(value.toString()); - return label; + SecurityManager securityManager = + Utilities.getSecurityManager(state); + SciDepartment department = (SciDepartment) m_itemModel. + getSelectedObject(state); + + boolean canEdit = securityManager.canAccess( + state.getRequest(), + SecurityManager.EDIT_ITEM, + department); + + if (canEdit) { + SciOrganization organization; + try { + organization = new SciOrganization((BigDecimal) key); + } catch (ObjectNotFoundException ex) { + logger.warn(String.format("No object with key '%s' found.", + key), + ex); + return new Label(value.toString()); + } + + ContentSection section = CMS.getContext().getContentSection(); + ItemResolver resolver = section.getItemResolver(); + Link link = new Link(String.format("%s (%s)", + value.toString(), + organization.getLanguage()), + resolver.generateItemURL(state, + organization, + section, + organization. + getVersion())); + + return link; + } else { + SciOrganization organization; + try { + organization = new SciOrganization((BigDecimal) key); + } catch (ObjectNotFoundException ex) { + logger.warn(String.format("No object with key '%s' found.", + key), + ex); + return new Label(value.toString()); + } + + Label label = new Label( + String.format("%s (%s)", + value.toString(), + organization.getLanguage())); + return label; + } + } } @@ -216,7 +276,8 @@ public class SciDepartmentOrganizationSheet public void cellSelected(TableActionEvent event) { PageState state = event.getPageState(); - SciDepartment department = (SciDepartment) m_itemModel.getSelectedObject( + SciDepartment department = + (SciDepartment) m_itemModel.getSelectedObject( state); TableColumn column = getColumnModel().get(event.getColumn().intValue()); diff --git a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationDepartmentAddForm.java b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationDepartmentAddForm.java index eb3ca9c7c..29116e822 100644 --- a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationDepartmentAddForm.java +++ b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationDepartmentAddForm.java @@ -78,10 +78,33 @@ public class SciOrganizationDepartmentAddForm getSelectedObject(state); if (!(this.getSaveCancelSection().getCancelButton(). - isSelected(state))) { - orga.addDepartment((SciDepartment) data.get(ITEM_SEARCH)); + isSelected(state))) { + SciDepartment department = (SciDepartment) data.get(ITEM_SEARCH); + + department = (SciDepartment) department.getContentBundle(). + getInstance(orga.getLanguage()); + + orga.addDepartment(department); + //orga.addDepartment((SciDepartment) data.get(ITEM_SEARCH)); } init(fse); } + + @Override + public void validate(FormSectionEvent fse) throws FormProcessException { + final PageState state = fse.getPageState(); + final FormData data = fse.getFormData(); + + SciOrganization orga = (SciOrganization) getItemSelectionModel(). + getSelectedObject(state); + + SciDepartment department = (SciDepartment) data.get(ITEM_SEARCH); + + if (!(department.getContentBundle().hasInstance(orga.getLanguage()))) { + data.addError( + SciOrganizationGlobalizationUtil.globalize( + "sciorganization.ui.organization.department.add.no_suitable_language_variant")); + } + } } diff --git a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationDepartmentsTable.java b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationDepartmentsTable.java index 6543a5ff7..9d918e67f 100644 --- a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationDepartmentsTable.java +++ b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationDepartmentsTable.java @@ -221,12 +221,13 @@ public class SciOrganizationDepartmentsTable key), ex); return new Label(value.toString()); - } ContentSection section = CMS.getContext().getContentSection(); ItemResolver resolver = section.getItemResolver(); - Link link = new Link(value.toString(), + Link link = new Link(String.format("%s (%s)", + value.toString(), + department.getLanguage()), resolver.generateItemURL(state, department, section, @@ -236,7 +237,19 @@ public class SciOrganizationDepartmentsTable return link; } else { - Label label = new Label(value.toString()); + SciDepartment department; + try { + department = new SciDepartment((BigDecimal) key); + } catch (ObjectNotFoundException ex) { + s_log.warn(String.format("No object with key '%s' found.", + key), + ex); + return new Label(value.toString()); + } + + Label label = new Label(String.format("%s (%s)", + value.toString(), + department.getLanguage())); return label; } } diff --git a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationResources.properties b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationResources.properties index 3f0c4e791..cfebff613 100644 --- a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationResources.properties +++ b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationResources.properties @@ -178,3 +178,5 @@ scimember.ui.project.confirm_remove=Do you really want to remove this associatio scimember.ui.project.select_project=Project scimember.ui.projects.edit_assoc=Edit association sciorganization.ui.project.description=Description of project +sciorganization.ui.organization.department.add.no_suitable_language_variant=The selected item has no language variant for the language of the current item. Please add an suitable language variant to the item to add before adding it. +sciorganization.ui.department.organization.add.no_suitable_language_variant=The selected item has no language variant for the language of the current item. Please add an suitable language variant to the item to add before adding it. diff --git a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationResources_de.properties b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationResources_de.properties index 5376c4f47..21caea601 100644 --- a/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationResources_de.properties +++ b/ccm-sci-types-organization/src/com/arsdigita/cms/contenttypes/ui/SciOrganizationResources_de.properties @@ -178,3 +178,5 @@ scimember.ui.project.confirm_remove=Wollen Sie diese Verkn\u00fcpfung wirklich e scimember.ui.project.select_project=Projekt scimember.ui.projects.edit_assoc=Verkn\u00fcpfung bearbeiten sciorganization.ui.project.description=Projektbeschreibung +sciorganization.ui.organization.department.add.no_suitable_language_variant=Das ausgew\u00e4hlte ContentItem besitzt keine Sprachvariante f\u00fcr die Sprache dieses Items und kann daher nicht hinzugef\u00fcgt werden. +sciorganization.ui.department.organization.add.no_suitable_language_variant=Das ausgew\u00e4hlte ContentItem besitzt keine Sprachvariante f\u00fcr die Sprache dieses Items und kann daher nicht hinzugef\u00fcgt werden.