View Javadoc

1   /*
2   
3   This software is OSI Certified Open Source Software.
4   OSI Certified is a certification mark of the Open Source Initiative.
5   
6   The license (Mozilla version 1.0) can be read at the MMBase site.
7   See http://www.MMBase.org/license
8   
9   */
10  package net.sf.mmapps.commons.bridge;
11  
12  import org.mmbase.bridge.*;
13  import org.mmbase.util.logging.Logger;
14  import org.mmbase.util.logging.Logging;
15  
16  
17  public class CloneUtil {
18  
19      /*** MMbase logging system */
20      private static Logger log = Logging.getLoggerInstance(CloneUtil.class.getName());
21      
22      private CloneUtil() {
23          // utility
24      }
25      
26      /***
27       * Clone a node with all relations
28       *
29       * @param localNode the node to be cloned
30       * @return  the cloned copy of localNode
31       */
32      public static Node cloneNodeWithRelations(Node localNode) {
33        log.debug("clone node (number,type)" +
34                  localNode.getNumber() + "," + localNode.getNodeManager().getName() + ")");
35  
36        Node newNode = cloneNode(localNode);
37        if (newNode == null) {
38           throw new NullPointerException("clone node #" + localNode.getNumber() + " returned null");
39        }
40        else {
41           if (log.isDebugEnabled()) {
42              log.debug("cloned the node to the new cloud new node(number,type)" +
43                     newNode.getNumber() + "," + newNode.getNodeManager().getName() + ")");
44           }
45        }
46        cloneRelations(localNode, newNode);
47  
48        return newNode;
49      }
50  
51      /***
52       * Clone a node to a cloud, including any fields without keeping administrative information
53       *
54       * @param localNode the node to clone
55       * @return the newly created node in the other cloud
56       */
57      public static Node cloneNode(Node localNode) {
58         if (isRelation(localNode)) {
59            return cloneRelation(localNode);
60         }
61         else {
62           NodeManager localNodeManager = localNode.getNodeManager();
63           NodeManager nodeManager = localNode.getCloud().getNodeManager(localNodeManager.getName());
64           Node newNode = nodeManager.createNode();
65  
66           FieldIterator fields = localNodeManager.getFields().fieldIterator();
67           while (fields.hasNext()) {
68              Field field = fields.nextField();
69              String fieldName = field.getName();
70  
71              if (field.getState() == Field.STATE_PERSISTENT) {
72                  if (!(fieldName.equals("owner") || fieldName.equals("number") ||
73                        fieldName.equals("otype") ||
74                        (fieldName.indexOf("_") == 0))) {
75                     cloneNodeField(localNode, newNode, field);
76                  }
77              }
78           }
79           newNode.commit();
80  
81           return newNode;
82         }
83      }
84      
85      /***
86       * cloneNodeField copies node fields from one node to an other
87       * @param sourceNode the source node
88       * @param destinationNode destination node
89       * @param field the field to clone
90       */
91      public static void cloneNodeField(Node sourceNode, Node destinationNode,
92         Field field) {
93         String fieldName = field.getName();
94         int fieldType = field.getType();
95  
96         switch (fieldType) {
97         case Field.TYPE_BINARY:
98            destinationNode.setByteValue(fieldName,
99               sourceNode.getByteValue(fieldName));
100           break;
101        case Field.TYPE_BOOLEAN:
102            destinationNode.setBooleanValue(fieldName,
103               sourceNode.getBooleanValue(fieldName));
104            break;
105        case Field.TYPE_DATETIME:
106            destinationNode.setDateValue(fieldName,
107               sourceNode.getDateValue(fieldName));
108            break;
109        case Field.TYPE_DOUBLE:
110           destinationNode.setDoubleValue(fieldName,
111              sourceNode.getDoubleValue(fieldName));
112           break;
113        case Field.TYPE_FLOAT:
114           destinationNode.setFloatValue(fieldName,
115              sourceNode.getFloatValue(fieldName));
116           break;
117        case Field.TYPE_INTEGER:
118           destinationNode.setIntValue(fieldName,
119              sourceNode.getIntValue(fieldName));
120           break;
121        case Field.TYPE_LONG:
122           destinationNode.setLongValue(fieldName,
123              sourceNode.getIntValue(fieldName));
124           break;
125        case Field.TYPE_NODE:
126            destinationNode.setNodeValue(fieldName,
127               sourceNode.getNodeValue(fieldName));
128            break;
129        case Field.TYPE_STRING:
130           destinationNode.setStringValue(fieldName,
131              sourceNode.getStringValue(fieldName));
132           break;
133        default:
134           destinationNode.setValue(fieldName, sourceNode.getValue(fieldName));
135        }
136     }
137 
138     public static Node cloneRelation(Node localRelation) {
139         Node sourceNode = localRelation.getNodeValue("snumber");
140         Node destinationNode = localRelation.getNodeValue("dnumber");
141 
142         return cloneRelation(localRelation, sourceNode, destinationNode);
143     }
144 
145     public static Node cloneRelation(Node localRelation, Node sourceNode, Node destinationNode) {
146         RelationManager relationManager = null;
147         if (localRelation instanceof Relation) {
148             Relation localRel = (Relation) localRelation;
149             relationManager = localRel.getRelationManager();
150         }
151         else {
152             Node relationTypeNode = localRelation.getNodeValue("rnumber");
153             String relName = relationTypeNode.getStringValue("sname");
154             relationManager = localRelation.getCloud().getRelationManager(sourceNode.getNodeManager().getName(),
155                                                destinationNode.getNodeManager().getName(),
156                                                relName);
157         }
158         Relation newRelation = relationManager.createRelation(sourceNode, destinationNode);
159 
160         FieldIterator fields = localRelation.getNodeManager().getFields().fieldIterator();
161         while (fields.hasNext()) {
162             Field field = fields.nextField();
163             String fieldName = field.getName();
164 
165             if (field.getState() == Field.STATE_PERSISTENT) {
166                 if (!(fieldName.equals("owner") || fieldName.equals("number")
167                         || fieldName.equals("otype") || (fieldName.indexOf("_") == 0)
168                         || fieldName.equals("snumber") || fieldName.equals("dir")
169                         || fieldName.equals("dnumber") || fieldName.equals("rnumber"))) {
170                     cloneNodeField(localRelation, newRelation, field);
171                 }
172             }
173         }
174         newRelation.commit();
175 
176         return newRelation;
177     }
178 
179     public static void cloneRelations(Node localNode, Node newNode) {
180        RelationIterator ri = localNode.getRelations().relationIterator();
181        if (ri.hasNext()) {
182           log.debug("the local node has relations");
183        }
184        while (ri.hasNext()) {
185           Relation rel = ri.nextRelation();
186           if (rel.getSource().getNumber() == localNode.getNumber()) {
187               cloneRelation(rel, newNode, rel.getDestination());
188           } else {
189              if (rel.getDestination().getNumber() == localNode.getNumber()) {
190                  cloneRelation(rel, rel.getSource(), newNode);
191              }
192           }
193        }
194     }
195 
196     public static void cloneRelations(Node localNode, Node newNode, String relationName, String managerName) {
197         RelationIterator ri = localNode.getRelations(relationName, managerName).relationIterator();
198         if (ri.hasNext()) {
199            log.debug("the local node has relations");
200         }
201         while (ri.hasNext()) {
202            Relation rel = ri.nextRelation();
203            if (rel.getSource().getNumber() == localNode.getNumber()) {
204                cloneRelation(rel, newNode, rel.getDestination());
205            } else {
206               if (rel.getDestination().getNumber() == localNode.getNumber()) {
207                   cloneRelation(rel, rel.getSource(), newNode);
208               }
209            }
210         }
211      }
212     
213     public static void cloneAliasses(Node localNode, Node destNode) {
214         StringList list = localNode.getAliases();
215         for (int x = 0; x < list.size(); x++) {
216            destNode.createAlias(list.getString(x));
217         }
218      }
219     
220     /***
221      * quick test to see if node is a relation by testing fieldnames
222      * @param node Possible relation
223      * @return <code>true</code> when relation fields present
224      */
225     protected static boolean isRelation(Node node) {
226        FieldIterator fi = node.getNodeManager().getFields().fieldIterator();
227        int count = 0;
228 
229        while (fi.hasNext()) {
230           String name = fi.nextField().getName();
231 
232           if (name.equals("rnumber") || name.equals("snumber") ||
233                 name.equals("dnumber")) {
234              count++;
235           }
236        }
237 
238        if (count == 3) {
239           return true;
240        }
241 
242        return false;
243     }
244     
245 }