001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.bridge.implementation;
011:
012: import java.util.Collection;
013: import java.util.Map;
014:
015: import org.mmbase.bridge.*;
016: import org.mmbase.bridge.util.MapNode;
017: import org.mmbase.module.core.*;
018: import org.mmbase.module.corebuilders.*;
019: import org.mmbase.util.logging.Logger;
020: import org.mmbase.util.logging.Logging;
021:
022: /**
023: * @since MMBase-1.9
024: * @version $Id: AbstractNodeList.java,v 1.9 2008/02/27 11:46:52 michiel Exp $
025: */
026: public abstract class AbstractNodeList<E extends Node> extends
027: BasicList<E> {
028:
029: private static final Logger log = Logging
030: .getLoggerInstance(AbstractNodeList.class);
031:
032: protected final Cloud cloud;
033: protected final NodeManager nodeManager;
034:
035: public AbstractNodeList() {
036: super ();
037: this .cloud = null;
038: this .nodeManager = null;
039: }
040:
041: public AbstractNodeList(Collection c) {
042: super (c);
043: this .cloud = null;
044: this .nodeManager = null;
045: }
046:
047: AbstractNodeList(Collection c, Cloud cloud) {
048: super (c);
049: this .cloud = cloud;
050: this .nodeManager = null;
051: }
052:
053: AbstractNodeList(Collection c, NodeManager nodeManager) {
054: super (c);
055: this .nodeManager = nodeManager;
056: this .cloud = nodeManager.getCloud();
057: }
058:
059: protected E convert(Object o) {
060: if (o == null) {
061: log.debug("Null");
062: return null;
063: }
064:
065: if (log.isDebugEnabled()) {
066: log.debug("Converting " + o.getClass());
067: }
068:
069: Node node = convertWithBridgeToNode(cloud, nodeManager, o);
070: if (node == null) {
071: log.debug("Could not convert with bridge");
072: if (o instanceof MMObjectBuilder) { // a builder
073: node = cloud.getNodeManager(((MMObjectBuilder) o)
074: .getTableName());
075: } else {
076: MMObjectNode coreNode = (MMObjectNode) o;
077: node = convertMMObjectNodetoBridgeNode(coreNode);
078: }
079: //log.info("Found " + node.getClass() + " in " + getClass());
080: }
081: if (node == null) {
082: throw new RuntimeException("Could not convert "
083: + o.getClass() + " " + o);
084: }
085:
086: return (E) node;
087: }
088:
089: /**
090: * Converts an object to a Node, using only bridge.
091: * @return a Node, or <code>null</code> if o is either <code>null</code> or could not be
092: * converted.
093: */
094: public static Node convertWithBridgeToNode(Cloud cloud,
095: NodeManager nodeManager, Object o) {
096: if (o == null) {
097: return null;
098: } else if (o instanceof Node) {
099: return (Node) o;
100: } else if (o instanceof CharSequence) { // a string indicates a nodemanager by name, or, if numeric, a node number..
101: String s = o.toString();
102: if (org.mmbase.datatypes.StringDataType.NON_NEGATIVE_INTEGER_PATTERN
103: .matcher(s).matches()) {
104: return cloud.getNode(s);
105: } else {
106: if (cloud.hasNodeManager(s)) {
107: return cloud.getNodeManager(s);
108: } else { // an alias?
109: if (cloud.hasNode(s)) {
110: return cloud.getNode(s);
111: } else {
112: log.warn("No such node '" + s
113: + "'. Converting to null");
114: return null;
115: }
116: }
117: }
118: } else if (o instanceof Map) {
119: if (nodeManager == null) {
120: return new MapNode((Map) o, cloud);
121: } else {
122: return new MapNode((Map) o, nodeManager);
123: }
124: } else if (o instanceof Number) {
125: return cloud.getNode(((Number) o).intValue());
126: } else {
127: return null;
128: }
129: }
130:
131: protected Node convertMMObjectNodetoBridgeNode(MMObjectNode coreNode) {
132: Node node;
133: MMObjectBuilder coreBuilder = coreNode.getBuilder();
134: if (coreBuilder instanceof TypeDef) {
135: String builderName = coreNode.getStringValue("name");
136: if (cloud.hasNodeManager(builderName)) {
137: try {
138: node = cloud.getNodeManager(builderName);
139: } catch (Throwable t) {
140: node = getNode(cloud, coreNode);
141: }
142: } else {
143: node = getNode(cloud, coreNode);
144: }
145: } else if (coreBuilder instanceof RelDef) {
146: node = cloud.getRelationManager(coreNode
147: .getStringValue("sname"));
148: } else if (coreBuilder instanceof TypeRel) {
149: int snumber = coreNode.getIntValue("snumber");
150: int dnumber = coreNode.getIntValue("dnumber");
151: int rnumber = coreNode.getIntValue("rnumber");
152: NodeManager nm1;
153: if (cloud.hasNode(snumber)) {
154: nm1 = castToNodeManager(cloud.getNode(snumber));
155: } else {
156: log.warn("Source of typerel "
157: + coreNode.getNumber()
158: + " is "
159: + (coreNode.isNull("snumber") ? "NULL" : ""
160: + snumber));
161: nm1 = cloud.getNodeManager("object");
162: }
163: NodeManager nm2;
164: if (cloud.hasNode(dnumber)) {
165: nm2 = castToNodeManager(cloud.getNode(dnumber));
166: } else {
167: log.warn("Destination of typerel "
168: + coreNode.getNumber()
169: + " is "
170: + (coreNode.isNull("dnumber") ? "NULL" : ""
171: + dnumber));
172: nm2 = cloud.getNodeManager("object");
173: }
174: Node role;
175: if (cloud.hasNode(rnumber)) {
176: role = cloud.getNode(rnumber);
177: } else {
178: log.warn("Role of typerel "
179: + coreNode.getNumber()
180: + " is "
181: + (coreNode.isNull("rnumber") ? "NULL" : ""
182: + rnumber));
183: role = cloud.getNode(BasicCloudContext.mmb.getRelDef()
184: .getNumberByName("related"));
185: }
186: node = cloud.getRelationManager(nm1.getName(), nm2
187: .getName(), role.getStringValue("sname"));
188: } else if (coreBuilder instanceof InsRel) {
189: node = getNode(cloud, coreNode);
190: } else if (coreNode instanceof org.mmbase.module.core.VirtualNode) {
191: MMObjectBuilder builder = coreNode.getBuilder();
192: if (builder instanceof VirtualBuilder) {
193: if (nodeManager != null) {
194: node = new VirtualNode(
195: cloud,
196: (org.mmbase.module.core.VirtualNode) coreNode,
197: nodeManager);
198: } else {
199: node = new VirtualNode(
200: (org.mmbase.module.core.VirtualNode) coreNode,
201: cloud);
202: }
203: } else {
204: node = new VirtualNode(cloud,
205: (org.mmbase.module.core.VirtualNode) coreNode,
206: cloud.getNodeManager(builder.getObjectType()));
207: }
208: } else {
209: node = getNode(cloud, coreNode);
210: }
211: return node;
212: }
213:
214: /**
215: * since MMBase 1.8
216: */
217: protected NodeManager castToNodeManager(Node n) {
218: if (n instanceof NodeManager) {
219: return (NodeManager) n;
220: } else {
221: log.error("Node " + n.getNumber()
222: + " is not a node manager (but a "
223: + n.getNodeManager()
224: + "), taking it Object for now");
225: return cloud.getNodeManager("object");
226: }
227: }
228:
229: /**
230: * @since MMBase-1.8.4
231: */
232: protected Node getNode(Cloud c, MMObjectNode coreNode) {
233: int n = coreNode.getNumber();
234: if (n == -1) {
235: String[] na = coreNode.getStringValue("_number").split("_");
236: if (na.length == 2) {
237: if (cloud.hasNode(na[1])) {
238: return cloud.getNode(na[1]);
239: } else {
240: return new BasicNode(coreNode, (BasicCloud) c);
241: }
242: } else {
243: throw new RuntimeException("Could not make a Node of "
244: + coreNode);
245: }
246: } else {
247: if (cloud.hasNode(n)) {
248: return cloud.getNode(n);
249: } else {
250: return new BasicNode(coreNode, (BasicCloud) c);
251: }
252: }
253: }
254:
255: }
|