Update of
/var/cvs/contributions/CMSContainer/cmsc/contentrepository/src/java/com/finalist/cmsc/repository
In directory james.mmbase.org:/tmp/cvs-serv4220
Modified Files:
RepositoryUtil.java
Log Message:
CMSC-1298 Clone channel feature
See also:
http://cvs.mmbase.org/viewcvs/contributions/CMSContainer/cmsc/contentrepository/src/java/com/finalist/cmsc/repository
See also: http://www.mmbase.org/jira/browse/CMSC-1298
Index: RepositoryUtil.java
===================================================================
RCS file:
/var/cvs/contributions/CMSContainer/cmsc/contentrepository/src/java/com/finalist/cmsc/repository/RepositoryUtil.java,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -b -r1.34 -r1.35
--- RepositoryUtil.java 31 Dec 2008 14:05:52 -0000 1.34
+++ RepositoryUtil.java 23 Feb 2009 08:40:41 -0000 1.35
@@ -7,14 +7,32 @@
*/
package com.finalist.cmsc.repository;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
import net.sf.mmapps.commons.bridge.CloneUtil;
import net.sf.mmapps.commons.bridge.NodeFieldComparator;
import net.sf.mmapps.modules.cloudprovider.CloudProviderFactory;
import org.apache.commons.lang.StringUtils;
-import org.mmbase.bridge.*;
+import org.mmbase.bridge.Cloud;
+import org.mmbase.bridge.Field;
+import org.mmbase.bridge.FieldIterator;
+import org.mmbase.bridge.Node;
+import org.mmbase.bridge.NodeList;
+import org.mmbase.bridge.NodeManager;
+import org.mmbase.bridge.NodeQuery;
+import org.mmbase.bridge.Relation;
+import org.mmbase.bridge.RelationIterator;
+import org.mmbase.bridge.RelationList;
+import org.mmbase.bridge.RelationManager;
import org.mmbase.bridge.util.Queries;
import org.mmbase.bridge.util.SearchUtil;
import org.mmbase.storage.search.FieldValueDateConstraint;
@@ -24,9 +42,12 @@
import org.mmbase.util.logging.Logger;
import org.mmbase.util.logging.Logging;
+import com.finalist.cmsc.mmbase.PropertiesUtil;
import com.finalist.cmsc.mmbase.RelationUtil;
import com.finalist.cmsc.mmbase.TreeUtil;
-import com.finalist.cmsc.security.*;
+import com.finalist.cmsc.security.Role;
+import com.finalist.cmsc.security.SecurityUtil;
+import com.finalist.cmsc.security.UserRole;
import com.finalist.cmsc.security.forms.RolesInfo;
public final class RepositoryUtil {
@@ -1165,9 +1186,23 @@
Node childChannel = iter.next();
copyChannel(childChannel, newChannel);
}
+ String cloneCopy = PropertiesUtil.getProperty("clonecopy");
+ if(cloneCopy != null && "true".equalsIgnoreCase(cloneCopy)) {
+ StringBuilder output = new StringBuilder().append("Start");
+ Map<Integer, Integer> copiedNodes = new HashMap<Integer,
Integer>();
+ List<Integer> channelNumbers = new ArrayList<Integer>();
+ cloneAssetNodes(sourceChannel,newChannel,copiedNodes,output);
+ iterateChannels(sourceChannel,channelNumbers);
+ cloneRelatedNodes(sourceChannel,
newChannel,copiedNodes,output,channelNumbers);
+ output.append("<br/><br/>copiedNodes has #" + copiedNodes.size() +
":<br/>" + copiedNodes.toString());
+ if(log.isDebugEnabled()) {
+ log.debug("#################:"+output.toString());
+ }
+ }
+ else {
CloneUtil.cloneRelations(sourceChannel, newChannel, CONTENTREL,
CONTENTELEMENT);
-
+ }
return newChannel;
}
return null;
@@ -1344,4 +1379,229 @@
}
return query.getNodeManager().getList(query);
}
+ public static void cloneRelatedNodes(Node sourceNode,Node
destNode,Map<Integer, Integer> copiedNodes ,StringBuilder output,List<Integer>
channels) {
+ List<Relation> relations = sourceNode.getRelations(null, null,
"destination");
+
+ for (Relation rel : relations) {
+ if(rel == null) {
+ output.append("skipped " + rel + "; ");
+ continue; //Skip contentchannels and collection channels.
+ }
+ if (! rel.isRelation()) {
+ output.append("skipped " + rel + "; ");
+ continue; //Skip contentchannels and collection channels.
+ }
+ RelationManager relManager = rel.getRelationManager();
+ if (relManager == null) {
+ //When a relation exists, but it is not defined in the typedef,
the relManager could not be found and resolves in null
+ //Apparently, there is a typedef missing in the MMBase typedef
table. Check the numbers in the logfile and add the relation to fix it!
+ //You need to cleanrun the script again (from previous database)
or fix these listed nodes by hand!
+ output.append("strangely not found relManager for " +
rel.getNumber() + ", please check destNode(" + sourceNode.getNumber() + "|" +
destNode.getNumber() + ") (might need to add a relation in typedef table!);");
+ continue;
+ }
+
+ if (!(AssetElementUtil.isAssetElement(rel.getDestination()) ||
ContentElementUtil.isContentElement(rel.getDestination()))) {
+ output.append("skipped " + relManager.getName() + "; ");
+ continue; //Skip contentchannels and collection channels.
+ }
+
+ if (!isRelatedWithCurrentChannelTree(rel.getDestination(),channels)) {
+ output.append("skipped " + relManager.getName() + "; ");
+ continue; //Skip contentchannels and collection channels.
+ }
+ if (isChannel(rel.getDestination()) ||
+ relManager.getName().equalsIgnoreCase("deletionrel")
+// || relManager.getName().equalsIgnoreCase("creationrel")
+ ) {
+ output.append("skipped " + relManager.getName() + "; ");
+ continue; //Skip contentchannels and collection channels.
+ }
+ else if
(rel.getNodeManager().getName().equals(ContentElementUtil.OWNERREL)) {
+ CloneUtil.cloneRelations(sourceNode, destNode,
ContentElementUtil.OWNERREL, SecurityUtil.USER);
+ output.append(ContentElementUtil.OWNERREL + " copied;");
+ } else
+ {
+ //*** Start cloning the node from sourceChild -> destChild
+ //If the related node should be cloned, dive into the node and
deepcopy it
+ Node sourceChild = rel.getDestination();
+ boolean cloned = false;
+
+ //Only clone node, when it hasn't been cloned before.
+ Node destChild;
+ if (copiedNodes.get(sourceChild.getNumber()) == null) {
+ destChild = cloneNode(sourceChild);
+
copiedNodes.put(Integer.valueOf(sourceChild.getNumber()),Integer.valueOf(destChild.getNumber()));
+ cloned = true;
+ //Logging
+ if (destChild.getNodeManager().hasField("name")) {
+ // output.append(destChild.getFieldValue("name") + " of ");
+ }
+ output.append(rel.getNodeManager().getName() + " cloned (" +
sourceNode.getNumber() + "|" + destChild.getNumber() + ");");
+ } else {
+ //Retrieve the already cloned node from the Map
+ destChild =
sourceNode.getCloud().getNode(copiedNodes.get(sourceChild.getNumber()));
+ output.append(rel.getNodeManager().getName() + " reused clone
(" + sourceChild.getNumber() + "|" + destChild.getNumber() + ");");
+ }
+ //*** End cloning node
+
+ //Create a new relation between the new node and its parent
+ Relation destRel = destNode.createRelation(destChild, relManager);
+ String relName = destRel.getNodeManager().getName();
+ if (relName.equalsIgnoreCase("posrel") ||
+ relName.equalsIgnoreCase("contentrel") ||
+ relName.equalsIgnoreCase("childrel") ||
+ relName.equalsIgnoreCase("detailimagerel")) {
+ destRel.setIntValue("pos", rel.getIntValue("pos"));
+ }
+ destRel.commit();
+
+ //If no clone was needed, but reused an existing clone, the
relations are fine already..continue!
+ if (!cloned) continue;
+
+ //Creation channels are skipped at copying relations, so do it by
hand.
+ if (hasCreationChannel(sourceChild) && isChannel(destNode)) {
+ addCreationChannel(destChild, destNode);
+ output.append("added creationrel to " + destChild.getNumber() +
";");
+ }
+
+ //If destChild is an image, also change title
+ if
(destChild.getNodeManager().getName().equalsIgnoreCase("images")) {
+ destChild.setStringValue("title",
destChild.getStringValue("title") + "-North");
+ destChild.commit();
+ }
+ output.append("[newRel:" + destNode.getNumber() + "," + relName
+ "];");
+
+// if
(destChild.getNodeManager().getName().equalsIgnoreCase("subject")) {
+ //Now go deeper into the tree
+ cloneRelatedNodes(sourceChild, destChild, copiedNodes,
output,channels);
+// }
+ }
+ }
+ }
+ public static Node cloneNode(Node localNode) {
+ if (isRelation(localNode)) {
+ return CloneUtil.cloneRelation(localNode);
+ }
+ else {
+ NodeManager localNodeManager = localNode.getNodeManager();
+ NodeManager nodeManager =
localNode.getCloud().getNodeManager(localNodeManager.getName());
+ Node newNode = nodeManager.createNode();
+
+ FieldIterator fields = localNodeManager.getFields().fieldIterator();
+ while (fields.hasNext()) {
+ Field field = fields.nextField();
+ String fieldName = field.getName();
+
+ if (field.getState() == Field.STATE_PERSISTENT) {
+ if (!(fieldName.equals("owner") || fieldName.equals("number") ||
+ fieldName.equals("otype") ||
+ (fieldName.indexOf("_") == 0))) {
+ cloneNodeField(localNode, newNode, field);
+ }
+ }
+ }
+ newNode.commit();
+
+ return newNode;
+ }
+ }
+
+ /**
+ * cloneNodeField copies node fields from one node to an other
+ *
+ * @param sourceNode
+ * the source node
+ * @param destinationNode
+ * destination node
+ * @param field
+ * the field to clone
+ */
+ public static void cloneNodeField(Node sourceNode, Node destinationNode,
Field field) {
+ String fieldName = field.getName();
+
+ if (destinationNode.getNodeManager().hasField(fieldName) == true) {
+ Field sourceField = sourceNode.getNodeManager().getField(fieldName);
+ if (sourceField.getState() != Field.STATE_SYSTEM &&
!sourceField.isVirtual()) {
+ destinationNode.setValueWithoutProcess(fieldName,
+ sourceNode.getValueWithoutProcess(fieldName));
+ }
+ }
+ }
+
+ /**
+ * quick test to see if node is a relation by testing fieldnames
+ * @param node Possible relation
+ * @return <code>true</code> when relation fields present
+ */
+ public static boolean isRelation(Node node) {
+ FieldIterator fi = node.getNodeManager().getFields().fieldIterator();
+ int count = 0;
+
+ while (fi.hasNext()) {
+ String name = fi.nextField().getName();
+
+ if (name.equals("rnumber") || name.equals("snumber") ||
+ name.equals("dnumber")) {
+ count++;
+ }
+ }
+
+ if (count == 3) {
+ return true;
+ }
+
+ return false;
+ }
+ public static void iterateChannels(Node sourceChannel, List<Integer>
channelList) {
+ NodeList children = RepositoryUtil.getOrderedChildren(sourceChannel);
+ channelList.add(sourceChannel.getNumber());
+ for (Iterator<Node> iter = children.iterator(); iter.hasNext();) {
+ Node childChannel = iter.next();
+ iterateChannels(childChannel, channelList);
+ }
+ }
+
+ /**
+ * check the node if it is in the current channel tree
+ * @param sourceNode
+ * @param channels
+ * @return
+ */
+ public static boolean isRelatedWithCurrentChannelTree(Node
sourceNode,List<Integer> channels) {
+
+ if (AssetElementUtil.isAssetElement(sourceNode)) {
+
+ Node creationNode = getCreationChannel(sourceNode);
+ if(creationNode != null &&
channels.contains(creationNode.getNumber())) {
+ return true;
+ }
+ }
+ else if (ContentElementUtil.isContentElement(sourceNode)) {
+ NodeList contentChannels = getContentChannelsForContent(sourceNode);
+ for(int i = 0 ; i < contentChannels.size() ; i++) {
+ if (channels.contains(contentChannels.getNode(i).getNumber())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Clone related assets according to the channel
+ * @param sourceChannel source channel
+ * @param newChannel destination channel
+ * @param copiedNodes Nodes have been copied
+ * @param output
+ */
+ public static void cloneAssetNodes(Node sourceChannel,Node
newChannel,Map<Integer, Integer> copiedNodes ,StringBuilder output) {
+
+ List<Relation> relations = sourceChannel.getRelations("creationrel",
sourceChannel.getCloud().getNodeManager("assetelement"), SOURCE);
+ for (Relation rel : relations) {
+ Node sourceChild = rel.getSource();
+ Node destChild = CloneUtil.cloneNode(sourceChild);
+ copiedNodes.put(sourceChild.getNumber(), destChild.getNumber());
+ addAssetToChannel(destChild,newChannel);
+ }
+ }
}
_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs