Source Code Cross Referenced for ClusterNode.java in  » Database-ORM » MMBase » org » mmbase » module » core » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » MMBase » org.mmbase.module.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.module.core;
011:
012:        import java.util.*;
013:
014:        import org.mmbase.bridge.Field;
015:        import org.mmbase.util.logging.*;
016:        import org.mmbase.util.Casting;
017:
018:        /**
019:         * ClusterNode combines fields of different nodes in a single "virtual" node.
020:         * This corresponds to the way that an SQL "join" select statement combines
021:         * fields of different tables in result rows.
022:         * <p>
023:         * The individual fields are retrieved from a set of related nodes using a
024:         * multilevel query, i.e. a query joining tables using the relations between
025:         * the tables.
026:         * <p>
027:         * This class overrides a number of methods, allowing direct access to data in
028:         * the nodes which form the 'virtual' node.
029:         * <br />
030:         * In future releases, data will NOT be stored directkly in this node anymore.
031:         * Instead, it will be stored in the underlying MMObjectNodes.
032:         * For reasons of optiomalization, however, we cannot do this right now.
033:         * MMObjectNode will need a status field that allows us to recognize whether
034:         * it is fully loaded, partially loaded, or being edited.
035:         * This can then be checked in 'retrievevalue'.
036:         * In addition, to prevent caching conflicts, nodes will need to maintain
037:         * their references. This allows for a secure caching mechanism.
038:         * <br />
039:         * Among other things, this allows one to change values in a multilevel node,
040:         * or to access functionality that would otherwise be restricted to 'real'
041:         * nodes.
042:         *
043:         * @author Pierre van Rooden
044:         * @version $Id: ClusterNode.java,v 1.29 2007/07/23 13:51:02 michiel Exp $
045:         * @see ClusterBuilder
046:         */
047:        public class ClusterNode extends VirtualNode {
048:
049:            private static final Logger log = Logging
050:                    .getLoggerInstance(ClusterNode.class);
051:
052:            /**
053:             * Main contructor.
054:             * @param parent the node's parent
055:             */
056:            public ClusterNode(ClusterBuilder parent) {
057:                super (parent);
058:            }
059:
060:            /**
061:             * Main contructor.
062:             * @param parent the node's parent
063:             * @param nrofnodes Nr of referenced nodes.
064:             */
065:            public ClusterNode(ClusterBuilder parent, int nrofnodes) {
066:                super (parent);
067:            }
068:
069:            /**
070:             * Tests whether the data in a node is valid (throws an exception if this is not the case).
071:             * The call is performed on all loaded 'real' nodes. If a 'real' node has not previously been
072:             * forcably loaded, it is assumed to be correct.
073:             * @throws org.mmbase.module.core.InvalidDataException
074:             *      If the data was unrecoverably invalid
075:             *      (the references did not point to existing objects)
076:             */
077:            public void testValidData() throws InvalidDataException { // why is it public?
078:                throw new UnsupportedOperationException("ClusterNode "
079:                        + this .getClass().getName() + " removed since 1.8");
080:            };
081:
082:            /**
083:             * commit : commits the node to the database or other storage system.
084:             * This can only be done on a existing (inserted) node. it will use the
085:             * changed Vector as its base of what to commit/changed
086:             * @return <code>true</code> if the commit was succesfull, <code>false</code> is it failed
087:             */
088:            public boolean commit() {
089:                throw new UnsupportedOperationException("ClusterNode "
090:                        + this .getClass().getName() + " removed since 1.8");
091:            }
092:
093:            /**
094:             * Obtain the 'real' nodes, associated with a specified objectbuilder.
095:             * @param builderName the name of the builder of the requested node, as known
096:             *        within the virtual node
097:             * @return the node, or <code>null</code> if it does not exist or is unknown
098:             */
099:            public MMObjectNode getRealNode(String builderName) {
100:                if (builderName == null)
101:                    return null;
102:                Integer number = (Integer) retrieveValue(builderName
103:                        + ".number");
104:                if (number != null) {
105:                    return parent.getNode(number.intValue());
106:                }
107:                return null;
108:            }
109:
110:            /**
111:             * Stores a value in the values hashtable.
112:             * If the value is not stored in the virtualnode,
113:             * the 'real' node is used instead.
114:             * @param fieldName the name of the field to change
115:             * @param fieldValue the value to assign
116:             */
117:            public void storeValue(String fieldName, Object fieldValue) {
118:                super .storeValue(fieldName, fieldValue);
119:            }
120:
121:            /**
122:             * Sets a key/value pair in the main values of this node.
123:             * Note that if this node is a node in cache, the changes are immediately visible to
124:             * everyone, even if the changes are not committed.
125:             * The fieldname is added to the (public) 'changed' vector to track changes.
126:             * @param fieldName the name of the field to change
127:             * @param fieldValue the value to assign
128:             * @return always <code>true</code>
129:             */
130:            public boolean setValue(String fieldName, Object fieldValue) {
131:                // Circument interference by the database during initial loading of the node
132:                // This is not pretty, but the alternative is rewriting all support classes...
133:                if (initializing) {
134:                    if (!(parent instanceof  ClusterBuilder)) {
135:                        values.put(ClusterBuilder
136:                                .getFieldNameFromField(fieldName), fieldValue);
137:                    } else {
138:                        values.put(fieldName, fieldValue);
139:                    }
140:                    return true;
141:                }
142:                String builderName = getBuilderName(fieldName);
143:
144:                MMObjectNode n = getRealNode(builderName);
145:                if (n != null) {
146:                    String realFieldName = ClusterBuilder
147:                            .getFieldNameFromField(fieldName);
148:                    n.setValue(realFieldName, fieldValue);
149:                    values.remove(fieldName);
150:                    return true;
151:                }
152:                log.warn("Could not set field '" + fieldName + "')");
153:                return false; // or throw exception?
154:            }
155:
156:            /**
157:             * Determines the builder name of a specified fieldname, i.e.
158:             * "news" in "news.title",
159:             * @param fieldName the name of the field
160:             * @return the buidler name of the field
161:             */
162:            protected String getBuilderName(String fieldName) {
163:                int pos = fieldName.indexOf(".");
164:                if (pos == -1) {
165:                    return null;
166:                } else {
167:                    String builderName = fieldName.substring(0, pos);
168:                    int pos2 = builderName.lastIndexOf("(");
169:                    builderName = builderName.substring(pos2 + 1);
170:                    // XXX: we should check on commas and semicolons too... ?
171:                    return builderName;
172:                }
173:            }
174:
175:            // MM: special arrangment for if parent is not ClusterBuilder.
176:            // could give NPE so this is a fix...  (1.7)
177:            public MMObjectBuilder getBuilder() {
178:                if (parent instanceof  ClusterBuilder) {
179:                    return super .getBuilder();
180:                } else {
181:                    return parent;
182:                }
183:
184:            }
185:
186:            /**
187:             * Get a value of a certain field.
188:             * @param fieldName the name of the field who's data to return
189:             * @return the field's value as an <code>Object</code>
190:             */
191:            public Object getValue(final String fieldName) {
192:                String builderName = getBuilderName(fieldName);
193:                if (builderName == null) {
194:                    // there is no 'builder' specified,
195:                    // so the fieldname itself is a builder name
196:                    // -> so return the MMObjectNode for that buidler
197:                    if (parent instanceof  ClusterBuilder) {
198:                        return getRealNode(fieldName);
199:                    }
200:
201:                }
202:                Object o = super .getValue(fieldName);
203:                if (o == null) {
204:                    // the normal approach does not yield results.
205:                    // get the value from the original builder
206:                    MMObjectNode n = getRealNode(builderName);
207:                    if (n != null) {
208:                        o = n.getValue(ClusterBuilder
209:                                .getFieldNameFromField(fieldName));
210:                    } else {
211:                        // fall back to builder if this node doesn't contain a number to fetch te original
212:                        MMObjectBuilder bul = parent.mmb
213:                                .getMMObject(builderName);
214:                        if (bul != null) {
215:                            o = bul.getValue(this , fieldName);
216:                        } else {
217:                            throw new RuntimeException("Builder with name '"
218:                                    + builderName + "' does not exist");
219:                        }
220:                    }
221:                }
222:                return o;
223:            }
224:
225:            public long getSize(String fieldName) {
226:                String builder = getBuilderName(fieldName);
227:                if (builder == null) {
228:                    return super .getSize(fieldName);
229:                } else {
230:                    MMObjectNode n = getRealNode(builder);
231:                    if (n != null) {
232:                        return n.getSize(ClusterBuilder
233:                                .getFieldNameFromField(fieldName));
234:                    } else {
235:                        return super .getSize(fieldName);
236:                    }
237:                }
238:            }
239:
240:            /**
241:             * Get a value of a certain field.
242:             * The value is returned as a String. Non-string values are automatically converted to String.
243:             * @param fieldName the name of the field who's data to return
244:             * @return the field's value as a <code>String</code>
245:             */
246:            public String getStringValue(String fieldName) {
247:
248:                // try to get the value from the values table
249:                String tmp = Casting.toString(getValue(fieldName));
250:
251:                // check if the object is shorted
252:                if (tmp.equals(MMObjectNode.VALUE_SHORTED)) {
253:                    log.debug("getStringValue(): node=" + this 
254:                            + " -- fieldName " + fieldName);
255:                    // obtain the database type so we can check if what
256:                    // kind of object it is. this have be changed for
257:                    // multiple database support.
258:                    int type = getDBType(fieldName);
259:
260:                    log.debug("getStringValue(): fieldName " + fieldName
261:                            + " has type " + type);
262:                    // check if for known mapped types
263:                    if (type == Field.TYPE_STRING) {
264:
265:                        // determine actual node number for this field
266:                        // takes into account when in a multilevel node
267:                        int number = getIntValue(getBuilderName(fieldName)
268:                                + ".number");
269:                        tmp = parent.getShortedText(fieldName, parent
270:                                .getNode(number));
271:
272:                        // did we get a result then store it in the values for next use
273:                        if (tmp != null) {
274:                            // store the unmapped value (replacing the $SHORTED text)
275:                            storeValue(fieldName, tmp);
276:                        }
277:                    }
278:                }
279:                // return the found value
280:                return tmp;
281:            }
282:
283:            /**
284:             * Get a binary value of a certain field.
285:             * @param fieldName the name of the field who's data to return
286:             * @return the field's value as an <code>byte []</code> (binary/blob field)
287:             */
288:            public byte[] getByteValue(String fieldName) {
289:                // try to get the value from the values table
290:                Object obj = getValue(fieldName);
291:
292:                // we signal with a empty byte[] that its not obtained yet.
293:                if (obj instanceof  byte[]) {
294:                    // was allready unmapped so return the value
295:                    return (byte[]) obj;
296:                } else {
297:                    // determine actual node number for this field
298:                    // takes into account when in a multilevel node
299:                    int number = getIntValue(getBuilderName(fieldName)
300:                            + ".number");
301:                    // call our builder with the convert request this will probably
302:                    // map it to the database we are running.
303:                    byte[] b = parent.getShortedByte(fieldName, parent
304:                            .getNode(number));
305:
306:                    // we could in the future also leave it unmapped in the values
307:                    // or make this programmable per builder ?
308:                    storeValue(fieldName, b);
309:                    // return the unmapped value
310:                    return b;
311:                }
312:            }
313:
314:            /**
315:             * Tests whether one of the values of this node was changed since the last commit/insert.
316:             * @return <code>true</code> if changes have been made, <code>false</code> otherwise
317:             */
318:            public boolean isChanged() {
319:                throw new UnsupportedOperationException("ClusterNode "
320:                        + this .getClass().getName() + " removed since 1.8");
321:            }
322:
323:            /**
324:             * Return the relations of this node.
325:             * This is not allowed on a cluster node
326:             * @throws <code>RuntimeException</code>
327:             */
328:            public Enumeration<MMObjectNode> getRelations() {
329:                throw new RuntimeException(
330:                        "Cannot follow relations on a cluster node. ");
331:            }
332:
333:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.