/* * Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package com.arsdigita.cms; import com.arsdigita.domain.DomainObject; import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.domain.DomainService; import com.arsdigita.domain.InstantiatorNotFoundException; import com.arsdigita.persistence.DataAssociation; import com.arsdigita.persistence.DataAssociationCursor; import com.arsdigita.persistence.DataObject; import com.arsdigita.persistence.metadata.ObjectType; import com.arsdigita.persistence.metadata.Property; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * Recursively updates the "version" attribute of a content item to a * new value. For internal use only; users should never have to know * or care about this class. * * @author Stanislav Freidin * @version $Id: VersionUpdater.java 2090 2010-04-17 08:04:14Z pboy $ */ class VersionUpdater extends DomainService { private static org.apache.log4j.Logger s_log = org.apache.log4j.Logger.getLogger(VersionUpdater.class); // A map of visited OIDs. Helps prevent infinite recursion. // all objects copied so far. protected Set m_visited; // The new version tag for the items String m_newVersion; /** * Construct a new VersionUpdater */ protected VersionUpdater(String newVersion) { m_visited = new HashSet(); m_newVersion = newVersion; } /** * Recursively set the version of a ContentItem * * @param item the item */ public void updateItemVersion(ContentItem item) { // This seems wasteful, but in fact we need to specialize // the item anyway, in order to cache the right OID updateSingleObject(getDataObject(item)); } /** * Recursively traverse the object's children and set their versions * to the right thing * * @param src the parent object */ protected void updateChildren(DataObject src) { ObjectType type = src.getOID().getObjectType(); for(Iterator i = type.getProperties(); i.hasNext(); ) { Property prop = (Property) i.next(); // Skip scalars if (!prop.isRole()) continue; // Skip non-composites if (!prop.isComponent()) continue; String propName = prop.getName(); // Get the value of the property, skip nulls Object data = src.get(propName); if (data == null) continue; if(data instanceof DataObject) { updateSingleObject((DataObject)data); } else if (data instanceof DataAssociation) { // Association - iterate over it DataAssociationCursor daCursor = ((DataAssociation)data).getDataAssociationCursor(); while (daCursor.next()) { updateSingleObject(daCursor.getDataObject()); } } else { throw new IllegalStateException("Warning: unsupported property type " + data.getClass().getName()); } } } /** * Update the version of a single object, if it happens to be * a content item */ protected void updateSingleObject(DataObject src) { // Prevent infinite recursion if(m_visited.contains(src.getOID())) return; m_visited.add(src.getOID()); ContentItem item = null; try { DomainObject obj = DomainObjectFactory.newInstance(src); if(obj instanceof ContentItem) item = (ContentItem)obj; } catch (InstantiatorNotFoundException e) { // do nothing } if(item != null) { // Prevent unnecessary updates if(! (m_newVersion.equals(item.getVersion()))) { // Update the current item's version; this will // also have the effect of setting/unsetting the live version // for the master item.setVersion(m_newVersion); item.save(); } } updateChildren(src); } }