KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > module > gui > html > HtmlBase


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
11 package org.mmbase.module.gui.html;
12
13 import java.util.*;
14 import java.io.*;
15
16 import org.mmbase.core.CoreField;
17 import org.mmbase.module.*;
18 import org.mmbase.module.core.*;
19 import org.mmbase.module.builders.Jumpers;
20 import org.mmbase.module.corebuilders.FieldDefs;
21 import org.mmbase.storage.search.*;
22 import org.mmbase.storage.search.implementation.*;
23
24 import org.mmbase.util.*;
25 import org.mmbase.util.logging.*;
26
27 /**
28  * The module which provides access to the multimedia database
29  * it creates, deletes and gives you methods to keep track of
30  * multimedia objects. It does not give you direct methods for
31  * inserting and reading them thats done by other objects
32  *
33  * @application SCAN
34  * @author Daniel Ockeloen
35  * @version $Id: HtmlBase.java,v 1.54 2005/11/23 15:45:13 pierre Exp $
36  */

37 public class HtmlBase extends ProcessorModule {
38     /**
39      * Logging instance
40      */

41     private static Logger log = Logging.getLoggerInstance(HtmlBase.class.getName());
42
43     sessionsInterface sessions;
44     boolean scancache=false;
45     MMBase mmb=null;
46
47     // should use org.mmbase.cache!
48
private int multilevel_cachesize=300;
49     private MultilevelCacheHandler multilevel_cache;
50
51     public void init() {
52         scancache tmp=(scancache)getModule("SCANCACHE");
53
54         if (tmp!=null && tmp.getStatus()) scancache=true;
55
56         mmb=(MMBase)getModule("MMBASEROOT");
57         sessions=(sessionsInterface)getModule("SESSION");
58
59         // get size from properties
60
multilevel_cache=new MultilevelCacheHandler(mmb,multilevel_cachesize);
61     }
62
63     static Enumeration search(MMObjectBuilder bul, String JavaDoc where, String JavaDoc sorted, boolean direction) {
64         // In order to support this method:
65
// - Exceptions of type SearchQueryExceptions are caught.
66
// - The result is converted to a vector.
67
String JavaDoc directions = (direction? "UP": "DOWN");
68         Vector result = new Vector();
69         NodeSearchQuery query = getSearchQuery(bul, where, sorted, directions);
70         try {
71             List nodes = bul.getNodes(query);
72             result.addAll(nodes);
73         } catch (SearchQueryException e) {
74             log.error(e);
75         }
76         return result.elements();
77     }
78
79     static NodeSearchQuery getSearchQuery(MMObjectBuilder bul, String JavaDoc where, String JavaDoc sorted, String JavaDoc directions) {
80         NodeSearchQuery query = bul.getStorageConnector().getSearchQuery(where);
81
82         if (directions == null) {
83             directions = "";
84         }
85         StringTokenizer sortedTokenizer = new StringTokenizer(sorted, ",");
86         StringTokenizer directionsTokenizer = new StringTokenizer(directions, ",");
87
88         String JavaDoc direction = "UP";
89         while (sortedTokenizer.hasMoreElements()) {
90             String JavaDoc fieldName = sortedTokenizer.nextToken().trim();
91             CoreField coreField = bul.getField(fieldName);
92             if (coreField == null) {
93                 throw new IllegalArgumentException JavaDoc(
94                 "Not a known field of builder " + bul.getTableName()
95                 + ": '" + fieldName + "'");
96             }
97             StepField field = query.getField(coreField);
98             BasicSortOrder sortOrder = query.addSortOrder(field);
99             if (directionsTokenizer.hasMoreElements()) {
100                 direction = directionsTokenizer.nextToken().trim();
101             }
102             if (direction.equalsIgnoreCase("DOWN")) {
103                 sortOrder.setDirection(SortOrder.ORDER_DESCENDING);
104             } else {
105                 sortOrder.setDirection(SortOrder.ORDER_ASCENDING);
106             }
107         }
108         return query;
109     }
110
111     /**
112      */

113     public HtmlBase() {
114     }
115
116     /**
117      * Generate a list of values from a command to the processor
118      */

119     public Vector getList(scanpage sp,StringTagger tagger, String JavaDoc value) throws ParseException {
120         String JavaDoc line = Strip.DoubleQuote(value,Strip.BOTH);
121         StringTokenizer tok = new StringTokenizer(line,"-\n\r");
122         if (tok.hasMoreTokens()) {
123             String JavaDoc cmd=tok.nextToken();
124             if (cmd.equals("OBJECTS")) return doObjects(sp,tagger);
125             if (cmd.equals("RELATIONS")) return doRelations(sp,tagger);
126             if (cmd.equals("MULTILEVEL")) return doMultiLevel(sp,tagger);
127             if (cmd.equals("MULTI")) return doMultiLevel(sp,tagger);
128             if (cmd.equals("BUILDER")) return doBuilder(sp,tagger,tok);
129         }
130         return null;
131     }
132
133     /**
134      * show Objects
135      */

136     public Vector doObjects(scanpage sp, StringTagger tagger) {
137         Object JavaDoc tmp;
138         String JavaDoc result=null;
139         MMObjectNode node;
140         Vector results=new Vector();
141         String JavaDoc type=tagger.Value("TYPE");
142         String JavaDoc where=tagger.Value("WHERE");
143         String JavaDoc dbsort=tagger.Value("DBSORT");
144         String JavaDoc dbdir=tagger.Value("DBDIR");
145         MMObjectBuilder bul=mmb.getMMObject(type);
146         long begin=(long)System.currentTimeMillis(),len;
147         Enumeration e=null;
148         if (dbsort==null) {
149             e = bul.search(where);
150         } else {
151             if (dbdir==null) {
152                 e = search(bul,where,dbsort, true);
153             } else {
154                 if (dbdir.equals("DOWN")) {
155                     e = search(bul,where,dbsort,false);
156                 } else {
157                     e = search(bul,where,dbsort,true);
158                 }
159             }
160         }
161
162         for (;e.hasMoreElements();) {
163             node=(MMObjectNode)e.nextElement();
164             Enumeration f=tagger.Values("FIELDS").elements();
165             for (;f.hasMoreElements();) {
166
167                 String JavaDoc fieldname=Strip.DoubleQuote((String JavaDoc)f.nextElement(),Strip.BOTH);
168                 result=node.getStringValue(fieldname);
169
170                 if (result!=null && !result.equals("null")) {
171                     results.addElement(result);
172                 } else {
173                     results.addElement("");
174                 }
175             }
176         }
177         tagger.setValue("ITEMS",""+tagger.Values("FIELDS").size());
178         long end=(long)System.currentTimeMillis();
179         log.debug("doObjects("+type+")="+(end-begin)+" ms");
180         return results;
181     }
182
183     /**
184      * Creates a {@link org.mmbase.storage.search.FieldCompareConstraint
185      * FieldCompareConstraint}, based on parts of a field expression in a
186      * MMNODE expression.
187      *
188      * @param field The field
189      * @param comparison The second character of the comparison operator.
190      * @param strValue The value to compare with, represented as
191      * <code>String<code>.
192      * @return The constraint.
193      * @since MMBase-1.7
194      */

195     private BasicFieldValueConstraint parseFieldPart(StepField field, char comparison, String JavaDoc strValue) {
196
197         Object JavaDoc value = strValue;
198
199         // For numberical fields, convert string representation to Double.
200
if (field.getType() != FieldDefs.TYPE_STRING &&
201             field.getType() != FieldDefs.TYPE_XML &&
202             field.getType() != FieldDefs.TYPE_UNKNOWN) {
203                 // backwards comp fix. This is needed for the scan editors.
204
int length = strValue.length();
205                 if (strValue.charAt(0) == '*' && strValue.charAt(length - 1) == '*') {
206                     strValue = strValue.substring(1, length - 1);
207                 }
208                 value = Double.valueOf(strValue);
209         }
210
211         BasicFieldValueConstraint constraint =
212             new BasicFieldValueConstraint(field, value);
213
214         switch (comparison) {
215             case '=':
216             case 'E':
217                 // EQUAL (string field)
218
if (field.getType() == FieldDefs.TYPE_STRING ||
219                     field.getType() == FieldDefs.TYPE_XML) {
220                     // Strip first and last character of value, when
221
// equal to '*'.
222
String JavaDoc str = (String JavaDoc) value;
223                     int length = str.length();
224                     if (str.charAt(0) == '*' && str.charAt(length - 1) == '*') {
225                         value = str.substring(1, length - 1);
226                     }
227
228                     // Convert to LIKE comparison with wildchard characters
229
// before and after (legacy).
230
constraint.setValue('%' + (String JavaDoc) value + '%');
231                     constraint.setCaseSensitive(false);
232                     constraint.setOperator(FieldCompareConstraint.LIKE);
233
234                 // EQUAL (numerical field)
235
} else {
236                     constraint.setOperator(FieldCompareConstraint.EQUAL);
237                 }
238                 break;
239
240             case 'N':
241                 constraint.setOperator(FieldCompareConstraint.NOT_EQUAL);
242                 break;
243
244             case 'G':
245                 constraint.setOperator(FieldCompareConstraint.GREATER);
246                 break;
247
248             case 'g':
249                 constraint.setOperator(FieldCompareConstraint.GREATER_EQUAL);
250                 break;
251
252             case 'S':
253                 constraint.setOperator(FieldCompareConstraint.LESS);
254                 break;
255
256             case 's':
257                 constraint.setOperator(FieldCompareConstraint.LESS_EQUAL);
258                 break;
259
260             default:
261                 throw new IllegalArgumentException JavaDoc(
262                     "Invalid comparison character: '" + comparison + "'");
263         }
264         return constraint;
265     }
266
267     /**
268      * Creates query based on an MMNODE expression.
269      *
270      * @param expr The MMNODE expression.
271      * @return The query.
272      * @throws IllegalArgumentException when an invalid argument is supplied.
273      * @since MMBase-1.7
274      */

275     private NodeSearchQuery convertMMNodeSearch2Query(MMObjectBuilder builder, String JavaDoc expr) {
276         NodeSearchQuery query = new NodeSearchQuery(builder);
277         BasicCompositeConstraint constraints
278             = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND);
279         String JavaDoc logicalOperator = null;
280
281         // Strip leading string "MMNODE " from expression, parse
282
// fieldexpressions and logical operators.
283
// (legacy: eol characters '\n' and '\r' are interpreted as "AND NOT")
284
StringTokenizer tokenizer
285             = new StringTokenizer(expr.substring(7), "+-\n\r", true);
286         while (tokenizer.hasMoreTokens()) {
287             String JavaDoc fieldExpression = tokenizer.nextToken();
288
289             // Remove prefix if present (example episodes.title==).
290
int pos = fieldExpression.indexOf('.');
291             if (pos != -1) {
292                 fieldExpression = fieldExpression.substring(pos + 1);
293             }
294
295             // Break up field expression in fieldname, comparison operator
296
// and value.
297
pos = fieldExpression.indexOf('=');
298             if (pos != -1 && fieldExpression.length() > pos + 2) {
299                 String JavaDoc fieldName = fieldExpression.substring(0, pos);
300                 char comparison = fieldExpression.charAt(pos + 1);
301                 String JavaDoc value = fieldExpression.substring(pos + 2);
302
303                 // Add corresponding constraint to constraints.
304
FieldDefs fieldDefs = builder.getField(fieldName);
305                 if (fieldDefs == null) {
306                     throw new IllegalArgumentException JavaDoc(
307                         "Invalid MMNODE expression: " + expr);
308                 }
309                 StepField field = query.getField(fieldDefs);
310                 BasicConstraint constraint
311                     = parseFieldPart(field, comparison, value);
312                 constraints.addChild(constraint);
313
314                 // Set to inverse if preceded by a logical operator that is
315
// not equal to "+".
316
if (logicalOperator != null && !logicalOperator.equals("+")) {
317                     constraint.setInverse(true);
318                 }
319             } else {
320                 // Invalid expression.
321
throw new IllegalArgumentException JavaDoc(
322                     "Invalid MMNODE expression: " + expr);
323             }
324
325             // Read next logical operator.
326
if (tokenizer.hasMoreTokens()) {
327                 logicalOperator = tokenizer.nextToken();
328             }
329         }
330
331         List childs = constraints.getChilds();
332         if (childs.size() == 1) {
333             query.setConstraint((FieldValueConstraint) childs.get(0));
334         } else if (childs.size() > 1) {
335             query.setConstraint(constraints);
336         }
337         return query;
338     }
339
340     /**
341      * Returns a Vector containing all the objects that match the searchkeys. Only returns the object numbers.
342      * @since MMBase-1.8
343      * @param where scan expression that the objects need to fulfill
344      * @return a <code>Vector</code> containing all the object numbers that apply, <code>null</code> if en error occurred.
345      * @deprecated Use {@link #getNodes(NodeSearchQuery)
346      * getNodes(NodeSearchQuery} to perform a node search.
347      */

348     private Vector searchNumbers(MMObjectBuilder builder, String JavaDoc where) {
349         // In order to support this method:
350
// - Exceptions of type SearchQueryExceptions are caught.
351
// - The result is converted to a vector.
352
Vector results = new Vector();
353         NodeSearchQuery query;
354         if (where != null && where.startsWith("MMNODE ")) {
355             // MMNODE expression.
356
query = convertMMNodeSearch2Query(builder, where);
357         } else {
358             query = new NodeSearchQuery(builder);
359             QueryConvertor.setConstraint(query, where);
360         }
361
362         // Wrap in modifiable query, replace fields by just the "number"-field.
363
ModifiableQuery modifiedQuery = new ModifiableQuery(query);
364         Step step = (Step) query.getSteps().get(0);
365         FieldDefs numberFieldDefs = builder.getField(MMObjectBuilder.FIELD_NUMBER);
366         StepField field = query.getField(numberFieldDefs);
367         List newFields = new ArrayList(1);
368         newFields.add(field);
369         modifiedQuery.setFields(newFields);
370
371         try {
372             List resultNodes = mmb.getSearchQueryHandler().getNodes(modifiedQuery,
373                 new ResultBuilder(mmb, modifiedQuery));
374
375             // Extract the numbers from the result.
376
Iterator iResultNodes = resultNodes.iterator();
377             while (iResultNodes.hasNext()) {
378                 ResultNode resultNode = (ResultNode) iResultNodes.next();
379                 results.add(resultNode.getIntegerValue(MMObjectBuilder.FIELD_NUMBER));
380             }
381         } catch (SearchQueryException e) {
382             log.error(e);
383             results = null;
384         }
385         return results;
386     }
387
388     /**
389      * show Relations
390      */

391     public Vector doRelations(scanpage sp, StringTagger tagger) {
392         Object JavaDoc tmp;
393         MMObjectNode node;
394         MMObjectBuilder bul=null;
395         int otype=-1;
396         int snode=-1;
397         int onode=-1;
398         Vector results=new Vector();
399         Vector wherevector=null;
400         String JavaDoc type=tagger.Value("TYPE");
401         String JavaDoc where=tagger.Value("WHERE");
402
403         try {
404             String JavaDoc tm = tagger.Value("NODE");
405             MMObjectNode srcnode = mmb.getTypeDef().getNode(tm);
406             snode = srcnode.getIntValue("number");
407             bul = srcnode.getBuilder();
408
409             if (type!=null) {
410                 bul=mmb.getMMObject(type);
411                 if (bul==null) {
412                     throw new Exception JavaDoc("cannot find object type : "+type);
413                 }
414                 otype=bul.getNumber();
415             }
416             if ((where != null) && (bul != null)) {
417                 wherevector = searchNumbers(bul,where);
418             }
419             Iterator i = null;
420             if (type==null) {
421                 i=srcnode.getRelatedNodes().iterator();
422             } else {
423                 i=srcnode.getRelatedNodes(type).iterator();
424             }
425             while(i.hasNext()) {
426                 node=(MMObjectNode)i.next();
427                 if (where==null || wherevector.contains(new Integer JavaDoc(node.getIntValue("number")))) {
428                     for (Iterator f=tagger.Values("FIELDS").iterator(); f.hasNext();) {
429                         // hack hack this is way silly Strip needs to be fixed
430
tmp=node.getValue(Strip.DoubleQuote((String JavaDoc)f.next(),Strip.BOTH));
431                         if (tmp!=null && !tmp.equals("null")) {
432                             results.addElement(""+tmp);
433                         } else {
434                             results.addElement("");
435                         }
436                     }
437                 }
438             }
439             tagger.setValue("ITEMS",""+tagger.Values("FIELDS").size());
440         } catch(Exception JavaDoc e) {
441             log.error("doRelations("+sp.getUrl()+"): ERROR: node("+snode+"), type("+type+"), where("+where+"):"+e);
442             if (bul!=null) {
443                 log.error(Logging.stackTrace(e));
444             }
445         }
446         return results;
447     }
448
449
450     public String JavaDoc doGetRelationValue(scanpage sp, StringTokenizer tok) {
451         MMObjectBuilder bul = mmb.getMMObject("typedef");
452
453         // reads $MOD-MMBASE-GETRELATIONVALUE-12-23-title where 12 is the source
454
// number, 23 the target number and title the key of the relation
455
// value you want.
456
int snumber=-1;
457         int dnumber=-1;
458
459         //obtain source number
460
if (tok.hasMoreTokens()) {
461             try {
462                 snumber=Integer.parseInt(tok.nextToken());
463             } catch (Exception JavaDoc e) {
464                 return "wrong source node";
465             }
466         } else {
467             return "missing source node";
468         }
469
470
471         //obtain destination number
472
if (tok.hasMoreTokens()) {
473             try {
474                 dnumber=Integer.parseInt(tok.nextToken());
475             } catch (Exception JavaDoc e) {
476                 return "wrong destination node";
477             }
478         } else {
479             return "missing destination node";
480         }
481
482         //obtain field name
483
if (tok.hasMoreTokens()) {
484             String JavaDoc fieldname=tok.nextToken();
485             MMObjectNode snode=bul.getNode(""+snumber);
486             if (snode!=null) {
487                 for (Enumeration e=snode.getRelations();e.hasMoreElements();) {
488                     MMObjectNode inode=(MMObjectNode)e.nextElement();
489                     int s=inode.getIntValue("snumber");
490                     int d=inode.getIntValue("dnumber");
491                     if (d==dnumber || s==dnumber) {
492                         String JavaDoc result="";
493                         int n=inode.getIntValue("number");
494                         MMObjectNode dnode=(MMObjectNode)bul.getNode(""+n);
495                         if (dnode!=null) {
496                             result=dnode.getStringValue(fieldname);
497                             if (result!=null && !result.equals("null")) {
498                                 return result;
499                             } else {
500                                 return "";
501                             }
502                         }
503                     }
504                 }
505             } else {
506                 return "wrong source node";
507             }
508         } else {
509             return "missing fieldname";
510         }
511         return "";
512     }
513
514     public String JavaDoc doGetRelationCount(scanpage sp, StringTokenizer tok) {
515         MMObjectBuilder bul=mmb.getMMObject("typedef");
516         // reads $MOD-MMBASE-GETRELATIONCOUNT-12-images where 12 is the nodenumber
517
// and images is optional (if not it will return the total number of
518
// relations it has.
519

520         int snumber=-1;
521         int dnumber=-1;
522         String JavaDoc bulname=null;
523
524         //obtain source number
525
if (tok.hasMoreTokens()) {
526             try {
527                 snumber=Integer.parseInt(tok.nextToken());
528             } catch (Exception JavaDoc e) {
529                 return "wrong source node";
530             }
531         } else {
532             return "missing source node";
533         }
534
535         // obtain possible builder if not defined it will return the total count
536
if (tok.hasMoreTokens()) {
537             bulname=tok.nextToken();
538         }
539
540         MMObjectNode snode=bul.getNode(""+snumber);
541         if (snode!=null) {
542             if (bulname==null) {
543                 return ""+snode.getRelationCount();
544             } else {
545                 return ""+snode.getRelationCount(bulname);
546             }
547         } else {
548             return "0";
549         }
550     }
551
552     public String JavaDoc doSetRelationValue(scanpage sp, StringTokenizer tok) {
553         MMObjectBuilder bul=mmb.getMMObject("typedef");
554         // reads $MOD-MMBASE-GETRELATIONVALUE-12-23-title where 12 is the source
555
// number, 23 the target number and title the key of the relation
556
// value you want.
557
int snumber=-1;
558         int dnumber=-1;
559
560         //obtain source number
561
if (tok.hasMoreTokens()) {
562             try {
563                 snumber=Integer.parseInt(tok.nextToken());
564             } catch (Exception JavaDoc e) {
565                 return "wrong source node";
566             }
567         } else {
568             return "missing source node";
569         }
570
571         //obtain destination number
572
if (tok.hasMoreTokens()) {
573             try {
574                 dnumber=Integer.parseInt(tok.nextToken());
575             } catch (Exception JavaDoc e) {
576                 return "wrong destination node";
577             }
578         } else {
579             return "missing destination node";
580         }
581
582         //obtain field name
583
if (tok.hasMoreTokens()) {
584             String JavaDoc fieldname=tok.nextToken();
585             MMObjectNode snode=bul.getNode(""+snumber);
586             if (snode!=null) {
587                 for (Enumeration e=snode.getRelations();e.hasMoreElements();) {
588                     MMObjectNode inode=(MMObjectNode)e.nextElement();
589                     int s=inode.getIntValue("snumber");
590                     int d=inode.getIntValue("dnumber");
591                     if (d==dnumber || s==dnumber) {
592                         String JavaDoc result="";
593                         int n=inode.getIntValue("number");
594                         MMObjectNode dnode=(MMObjectNode)bul.getNode(""+n);
595                         if (dnode!=null) {
596                             result=dnode.getStringValue(fieldname);
597                             if (result!=null && !result.equals("null")) {
598                                 return result;
599                             } else {
600                                 return "";
601                             }
602                         }
603                     }
604                 }
605             } else {
606                 return "wrong source node";
607             }
608         } else {
609             return "missing fieldname";
610         }
611         return "";
612     }
613
614     /**
615      * show Relations
616      */

617     public Vector doRelations_replace(scanpage sp, StringTokenizer tok) {
618         Object JavaDoc tmp;
619         MMObjectNode node;
620         MMObjectBuilder bul=null;
621         int otype=-1;
622         int snode=-1;
623         int onode=-1;
624         Vector results=new Vector();
625         try {
626             String JavaDoc type=tok.nextToken();
627             bul=mmb.getMMObject(type);
628             otype=bul.getNumber();
629
630             snode=Integer.parseInt(tok.nextToken());
631             MMObjectNode node2=bul.getNode(snode);
632
633             Iterator i=null;
634             if (type==null) {
635                 i=node2.getRelatedNodes().iterator();
636             } else {
637                 i=node2.getRelatedNodes(type).iterator();
638             }
639             while(i.hasNext()) {
640                 node=(MMObjectNode)i.next();
641                 // use StringValue instead?
642
tmp=node.getValue(tok.nextToken());
643                 if (tmp!=null && !tmp.equals("null")) {
644                     results.addElement(""+tmp);
645                 } else {
646                     results.addElement("");
647                 }
648             }
649         } catch(Exception JavaDoc g) {
650             return null;
651         }
652         if (results.size()>0) {
653             return results;
654         } else {
655             return null;
656         }
657     }
658
659     /**
660      * Execute the commands provided in the form values
661      */

662     public boolean process(scanpage sp, Hashtable cmds,Hashtable vars) {
663         String JavaDoc cmdline,token;
664
665         for (Enumeration h = cmds.keys();h.hasMoreElements();) {
666             cmdline=(String JavaDoc)h.nextElement();
667             StringTokenizer tok = new StringTokenizer(cmdline,"-\n\r");
668             token = tok.nextToken();
669             if (token.equals("CACHEDELETE")) {
670                 log.debug("process(): DELETE ON CACHES");
671                 // InsRel.deleteNodeCache();
672
// InsRel.deleteRelationCache();
673

674             }
675         }
676         return false;
677     }
678
679     /**
680      * Handle a $MOD command
681      */

682     public String JavaDoc replace(scanpage sp, String JavaDoc cmds) {
683         StringTokenizer tok = new StringTokenizer(cmds,"-\n\r");
684         if (tok.hasMoreTokens()) {
685             String JavaDoc cmd=tok.nextToken();
686             if (cmd.equals("FIELD")) {
687                 return getObjectField(sp,tok);
688             } else if (cmd.equals("GETVALUE")) {
689                 return getBuilderValue(sp,tok);
690             } else if (cmd.equals("PROPERTY")) {
691                 return getObjectProperty(sp,tok);
692             } else if (cmd.equals("OTYPE")) {
693                 return getObjectType(sp,tok);
694             } else if (cmd.equals("TYPENAME")) {
695                 return getObjectTypeName(sp,tok);
696             } else if (cmd.equals("GUIINDICATOR")) {
697                 return getGuiIndicator(sp,tok);
698             } else if (cmd.equals("RELATION")) {
699                 Vector result=doRelations_replace(sp,tok);
700                 if (result!=null) return (String JavaDoc)result.elementAt(0);
701                 return "";
702             } else if (cmd.equals("GETRELATIONCOUNT")) {
703                 return doGetRelationCount(sp,tok);
704             } else if (cmd.equals("GETRELATIONVALUE")) {
705                 return doGetRelationValue(sp,tok);
706             } else if (cmd.equals("SETRELATIONVALUE")) {
707                 return doSetRelationValue(sp,tok);
708             } else if (cmd.equals("GETAUTHTYPE")) {
709                 return mmb.getAuthType();
710             } else if (cmd.equals("GETSEARCHAGE")) {
711                 return getSearchAge(tok);
712             } else if (cmd.equals("CACHE")) {
713                 return ""+doCache(sp,tok);
714             } else if (cmd.equals("GETDAYMARKER")) {
715                 return mmb.doGetAgeMarker(tok);
716                 // org.mmbase } else if (cmd.equals("FILEINFO")) {
717
// org.mmbase return (doFile(rq, tok));
718
} else if (cmd.equals("BUILDER")) {
719                 return doBuilderReplace(sp, tok);
720             } else if (cmd.equals("BUILDERACTIVE")) {
721                 return isBuilderActive(tok);
722             } else if (cmd.equals("GETJUMP")) {
723                 Jumpers bul=(Jumpers)mmb.getMMObject("jumpers");
724                 String JavaDoc url=bul.getJump(tok);
725                 if (url.startsWith("http://")) {
726                     return url;
727                 } else {
728                     return "";
729                 }
730             } else if (cmd.equals("GETNUMBER")) {
731                 // Get the number for a alias
732
return ""+mmb.getOAlias().getNumber(tok.nextToken());
733             } else if (cmd.equals("FIELDLENGTH")) {
734                 String JavaDoc s = getObjectField(sp,tok);
735                 if (s==null)
736                     return "0";
737                 else
738                     return ""+s.length();
739             }
740         }
741         return "No command defined";
742     }
743
744     String JavaDoc doCache(scanpage sp, StringTokenizer tok) {
745         String JavaDoc result="";
746         String JavaDoc cmd = tok.nextToken();
747         if (cmd.equals("SIZE")) {
748             if (tok.hasMoreTokens()) {
749                 String JavaDoc type = tok.nextToken();
750                 int i = mmb.getTypeDef().getIntValue(type);
751                 int j = 0;
752                 for (Iterator e = org.mmbase.cache.NodeCache.getCache().values().iterator(); e.hasNext();) {
753                     MMObjectNode n=(MMObjectNode)e.next();
754                     if (n.getOType()==i) j++;
755                 }
756                 result = "" + j;
757             } else {
758                 result = "" + org.mmbase.cache.NodeCache.getCache().size();
759             }
760         }
761         return result;
762     }
763
764     String JavaDoc getObjectType(scanpage sp, StringTokenizer tok) {
765         if (tok.hasMoreTokens()) {
766             String JavaDoc number=tok.nextToken();
767             MMObjectNode node=mmb.getTypeDef().getNode(number);
768             return mmb.getTypeDef().getValue(node.getIntValue("otype"));
769         }
770         return "unknown";
771     }
772
773     String JavaDoc getObjectTypeName(scanpage sp, StringTokenizer tok) {
774         if (tok.hasMoreTokens()) {
775             String JavaDoc number=tok.nextToken();
776             MMObjectNode node=mmb.getTypeDef().getNode(number);
777             return node.getName();
778         }
779         return "unknown";
780     }
781
782     String JavaDoc getGuiIndicator(scanpage sp, StringTokenizer tok) {
783         if (tok.hasMoreTokens()) {
784             String JavaDoc number=tok.nextToken();
785             MMObjectNode node=mmb.getTypeDef().getNode(number);
786             return node.getGUIIndicator();
787         }
788         return "unknown";
789     }
790
791     String JavaDoc getBuilderValue(scanpage sp, StringTokenizer tok) {
792         if (tok.hasMoreTokens()) {
793             String JavaDoc number=tok.nextToken();
794             String JavaDoc field="number";
795             if (tok.hasMoreTokens()) field=tok.nextToken();
796             MMObjectNode node=mmb.getTypeDef().getNode(number);
797             return ""+node.getValue(field);
798         }
799         return "";
800     }
801
802     String JavaDoc getObjectField(scanpage sp, StringTokenizer tok) {
803         if (tok.hasMoreTokens()) {
804             String JavaDoc nodeNr=tok.nextToken();
805             if( tok.hasMoreTokens()){
806                 String JavaDoc fieldname=tok.nextToken();
807                 String JavaDoc result=null;
808                 MMObjectBuilder bul=mmb.getMMObject("typedef");
809                 MMObjectNode node=bul.getNode(nodeNr);
810                 sessionInfo pagesession=getPageSession(sp);
811                 if (pagesession!=null) {
812                     pagesession.addSetValue("PAGECACHENODES",""+nodeNr);
813                 }
814                 if (result!=null) {
815                     return result;
816                 } else {
817                     if (node!=null) {
818                         result=node.getStringValue(fieldname);
819                     }
820                     if (result!=null && !result.equals("null")) {
821                         return result;
822                     } else {
823                         return "";
824                     }
825                 }
826             } else log.error("getObjectField(): no token fieldname found, nodenr("+nodeNr+"), url("+sp.getUrl()+")");
827         } else log.error("getObjectField(): no token nodenr found, url("+sp.getUrl()+")");
828         return "no command defined";
829     }
830
831     String JavaDoc getObjectProperty(scanpage sp, StringTokenizer tok) {
832         if (tok.hasMoreTokens()) {
833             String JavaDoc nodeNr=tok.nextToken();
834             String JavaDoc fieldname=tok.nextToken();
835             MMObjectBuilder bul=mmb.getMMObject("fielddef");
836             MMObjectNode node=bul.getNode(nodeNr);
837             sessionInfo pagesession=getPageSession(sp);
838             if (pagesession!=null) {
839                 pagesession.addSetValue("PAGECACHENODES",""+nodeNr);
840             }
841             MMObjectNode pnode=node.getProperty(fieldname);
842             if (pnode!=null) {
843                 return pnode.getStringValue("value");
844             } else {
845                 return "";
846             }
847         }
848         return "no command defined";
849     }
850
851     public Hashtable getSearchHash(Vector se,String JavaDoc mapper) {
852         Hashtable results=new Hashtable();
853         Enumeration t = se.elements();
854         MMObjectNode node;
855         while (t.hasMoreElements()) {
856             node=(MMObjectNode)t.nextElement();
857             results.put(new Integer JavaDoc(node.getIntValue(mapper)),node);
858         }
859         return results;
860     }
861
862     public String JavaDoc getWhereList(Vector se,String JavaDoc mapper) {
863         if (se==null) return null;
864         StringBuffer JavaDoc inlist = new StringBuffer JavaDoc();
865         inlist.append(" (");
866         Enumeration t = se.elements();
867         MMObjectNode node;
868         while (t.hasMoreElements()) {
869             node=(MMObjectNode)t.nextElement();
870             inlist.append(node.getIntValue(mapper) + ",");
871         }
872         if (inlist.length() >= 1 ) inlist.setLength(inlist.length()-1);
873         inlist.append( ") ");
874         return inlist.toString();
875     }
876
877     private String JavaDoc getFile(String JavaDoc file) {
878         String JavaDoc results=null;
879         byte[] buffer=getFileBytes(file);
880         if (buffer!=null) {
881             results=new String JavaDoc(buffer);
882         }
883         return results;
884     }
885
886     private byte[] getFileBytes(String JavaDoc file) {
887         File scanfile;
888         int filesize,len=0;
889         byte[] buffer;
890         FileInputStream scan;
891
892         scanfile = new File(file);
893         filesize = (int)scanfile.length();
894         buffer=new byte[filesize];
895         try {
896             scan = new FileInputStream(scanfile);
897             len=scan.read(buffer,0,filesize);
898             scan.close();
899         } catch(FileNotFoundException e) {
900             // oops we have a problem
901
} catch(IOException e) {}
902         if (len!=-1) {
903             return buffer;
904         }
905         return null;
906     }
907
908     public Vector doMultiLevel(scanpage sp, StringTagger tagger) throws MultiLevelParseException {
909         String JavaDoc result=null,fieldname;
910         Object JavaDoc tmp;
911         MMObjectNode node;
912         int snode=-1,onode=-1;
913         Integer JavaDoc hash;
914         Vector results=null,nodes,wherevector=null;
915         Enumeration e,f;
916         boolean reload=true;
917
918         if (scancache) reload=getReload(sp,tagger);
919
920         Vector type=tagger.Values("TYPE");
921         if ((type==null) || (type.size()==0)) throw new MultiLevelParseException("No TYPE specified");
922         Vector dbsort=tagger.Values("DBSORT");
923         Vector dbdir=tagger.Values("DBDIR");
924         String JavaDoc where=tagger.Value("WHERE");
925         Vector fields=tagger.Values("FIELDS");
926         if ((fields==null) || (fields.size()==0)) throw new MultiLevelParseException("No FIELDS specified");
927         Vector snodes=tagger.Values("NODE");
928         if ((snodes==null) || (snodes.size()==0)) throw new MultiLevelParseException("No NODE specified. Use NODE=\"-1\" to specify no node");
929         String JavaDoc distinct=tagger.Value("DISTINCT");
930         String JavaDoc searchdirs=tagger.Value("SEARCH");
931         int searchdir = RelationStep.DIRECTIONS_EITHER;
932         if (searchdirs!=null) {
933             searchdirs = searchdirs.toUpperCase();
934             if ("DESTINATION".equals(searchdirs)) {
935                 log.debug("DESTINATION");
936                 searchdir = RelationStep.DIRECTIONS_DESTINATION;
937             } else if ("SOURCE".equals(searchdirs)) {
938                 log.debug("SOURCE");
939                 searchdir = RelationStep.DIRECTIONS_SOURCE;
940             } else if ("BOTH".equals(searchdirs)) {
941                 log.debug("BOTH");
942                 searchdir = RelationStep.DIRECTIONS_BOTH;
943             } else if ("ALL".equals(searchdirs)) {
944                 log.debug("ALL");
945                 searchdir = RelationStep.DIRECTIONS_ALL;
946             }
947         }
948
949         tagger.setValue("ITEMS",""+fields.size());
950
951         hash=calcHashMultiLevel(tagger);
952         results=(Vector)multilevel_cache.get(hash);
953
954         //if (results==null || reload) {
955
if (results==null) {
956
957             if (reload) {
958                 log.debug("doMultiLevel cache RELOAD "+hash);
959             } else {
960                 log.debug("doMultiLevel cache MISS "+hash);
961             }
962             ClusterBuilder clusterBuilder = mmb.getClusterBuilder();
963             long begin=(long)System.currentTimeMillis(),len;
964
965             // strip the fields of their function codes so we can query the needed
966
// fields (teasers.number,shorted(episodes.title)
967
Vector cleanfields=removeFunctions(fields);
968             // now we have (teasers.number,episodes.title);
969

970             if (dbdir==null) {
971                 dbdir=new Vector();
972                 dbdir.addElement("UP"); // UP == ASC , DOWN =DESC
973
}
974             nodes = clusterBuilder.searchMultiLevelVector(snodes,cleanfields,distinct,type,where,dbsort,dbdir,searchdir);
975             if (nodes == null) {
976                 nodes = new Vector();
977             }
978             results = new Vector();
979             for (e=nodes.elements();e.hasMoreElements();) {
980                 node=(MMObjectNode)e.nextElement();
981                 for (f=fields.elements();f.hasMoreElements();) {
982                     // hack hack this is way silly, StringTagger needs to be fixed
983
fieldname=Strip.DoubleQuote((String JavaDoc)f.nextElement(),Strip.BOTH);
984                     if (fieldname.indexOf('(')>=0) {
985                         result=""+node.getValue(fieldname);
986                     } else {
987                         result=node.getStringValue(fieldname);
988                     }
989                     if (result!=null && !result.equals("null")) {
990                         results.addElement(result);
991                     } else {
992                         results.addElement("");
993                     }
994                 }
995             }
996
997             multilevel_cache.put(hash,results,type,tagger);
998             long end=(long)System.currentTimeMillis();
999             len=(end-begin);
1000            if (len>200) {
1001                log.debug("doMultilevel("+type+")="+(len)+" ms URI for page("+sp.req_line+")");
1002            }
1003        } else {
1004            log.debug("doMultiLevel cache HIT "+hash);
1005        }
1006        return results;
1007    }
1008
1009    /**
1010     * Belongs to doMultiLevel
1011     */

1012    private Integer JavaDoc calcHashMultiLevel(StringTagger tagger) {
1013        int hash=1;
1014        Object JavaDoc obj;
1015
1016        obj=tagger.Values("TYPE");
1017        hash = 31*hash + (obj==null ? 0 : obj.hashCode());
1018        obj=tagger.Values("DBSORT");
1019        hash = 31*hash + (obj==null ? 0 : obj.hashCode());
1020        obj=tagger.Values("DBDIR");
1021        hash = 31*hash + (obj==null ? 0 : obj.hashCode());
1022        obj=tagger.Value("WHERE");
1023        hash = 31*hash + (obj==null ? 0 : obj.hashCode());
1024        obj=tagger.Values("FIELDS");
1025        hash = 31*hash + (obj==null ? 0 : obj.hashCode());
1026        obj=tagger.Values("NODE");
1027        hash = 31*hash + (obj==null ? 0 : obj.hashCode());
1028        obj=tagger.Value("DISTINCT");
1029        hash = 31*hash + (obj==null ? 0 : obj.hashCode());
1030        obj=tagger.Value("SEARCH");
1031        hash = 31*hash + (obj==null ? 0 : obj.hashCode());
1032
1033        return new Integer JavaDoc(hash);
1034    }
1035
1036    public String JavaDoc doBuilderReplace(scanpage sp,StringTokenizer tok) {
1037        if (tok.hasMoreTokens()) {
1038            String JavaDoc type=tok.nextToken();
1039            MMObjectBuilder bul=mmb.getMMObject(type);
1040            if (bul!=null) {
1041                return bul.replace(sp,tok);
1042            }
1043        }
1044        return null;
1045    }
1046
1047    /**
1048     * Returns whether a builder is active.
1049     * @param tok tokenized command, should contain the builder name
1050     * @return <code>TRUE</code> if the builder is active, <code>FALSE</code> otherwise
1051     */

1052    public String JavaDoc isBuilderActive(StringTokenizer tok) {
1053        if (tok.hasMoreTokens()) {
1054            String JavaDoc type=tok.nextToken();
1055            MMObjectBuilder bul=mmb.getMMObject(type);
1056            if (bul!=null) {
1057                return "TRUE";
1058            }
1059        }
1060        return "FALSE";
1061    }
1062
1063    public Vector doBuilder(scanpage sp,StringTagger tagger, StringTokenizer tok) throws ParseException {
1064        if (tok.hasMoreTokens()) {
1065            String JavaDoc type=tok.nextToken();
1066            MMObjectBuilder bul=mmb.getMMObject(type);
1067            if (bul!=null) {
1068                return bul.getList(sp,tagger,tok);
1069            }
1070        }
1071        return null;
1072    }
1073
1074    private boolean getReload(scanpage sp,StringTagger tagger) {
1075        boolean rtn=false;
1076        boolean done=false;
1077        String JavaDoc memcache;
1078        if (tagger!=null) {
1079            memcache=tagger.Value("MEMCACHE");
1080            if (memcache!=null && memcache.equals("NO")) {
1081                rtn=true;
1082                done=true;
1083            }
1084        }
1085        if (!done && sessions!=null) {
1086            sessionInfo session=sessions.getSession(sp,sp.sname);
1087            if (session!=null) {
1088                rtn=sp.reload;
1089            }
1090            // When pagemaster calls set the reload on true
1091
if (sp.wantCache!=null && sp.wantCache.equals("PAGE")) {
1092                rtn=true;
1093            }
1094        } else {
1095            log.debug("getReload no session module loaded ? ");
1096        }
1097        return rtn;
1098    }
1099
1100    /**
1101     * @vpro refers to 'James'
1102     * @deprecated always returns null, do not use.
1103     */

1104    public sessionInfo getPageSession(scanpage sp) {
1105        if (sessions!=null) {
1106            // org.mmbase sessionInfo session=sessions.getSession(rq,rq.getSessionName());
1107
//sessionInfo session=sessions.getSession(sp.req,"james/1234");
1108
if( sp.sname == null || sp.sname.equals("")) {
1109                sp.sname = "james/1234";
1110            }
1111            sessionInfo session=sessions.getSession(sp,sp.sname);
1112            String JavaDoc cachetype=session.getValue("CACHE");
1113            if (cachetype!=null && cachetype.equals("PAGE")) {
1114                // return session;
1115
}
1116        }
1117        return null;
1118    }
1119
1120    public void stop() {}
1121
1122    String JavaDoc getObjectField(StringTokenizer tok) {
1123        if (tok.hasMoreTokens()) {
1124            String JavaDoc result=null;
1125            String JavaDoc nodeNr=tok.nextToken();
1126            String JavaDoc fieldname=tok.nextToken();
1127            MMObjectBuilder bul=mmb.getMMObject("fielddef");
1128            MMObjectNode node=bul.getNode(nodeNr);
1129            if (node!=null) {
1130                result=node.getStringValue(fieldname);
1131            }
1132            if (result!=null && !result.equals("null")) {
1133                return result;
1134            } else {
1135                return "";
1136            }
1137        }
1138        return "no command defined";
1139    }
1140
1141    public String JavaDoc doObjects(StringTagger tagger) {
1142        Object JavaDoc tmp;
1143        String JavaDoc result=null;
1144        MMObjectNode node;
1145        String JavaDoc results="";
1146        String JavaDoc type=tagger.Value("TYPE");
1147        String JavaDoc where=tagger.Value("WHERE");
1148        String JavaDoc dbsort=tagger.Value("DBSORT");
1149        String JavaDoc dbdir=tagger.Value("DBDIR");
1150        //log.debug("TYPE="+type);
1151
MMObjectBuilder bul=mmb.getMMObject(type);
1152        long begin=(long)System.currentTimeMillis(),len;
1153        Enumeration e=null;
1154        if (dbsort==null) {
1155            e = bul.search(where);
1156        } else {
1157            if (dbdir==null) {
1158                e = search(bul,where,dbsort, true);
1159            } else {
1160                if (dbdir.equals("DOWN")) {
1161                    e = search(bul,where,dbsort,false);
1162                } else {
1163                    e = search(bul,where,dbsort,true);
1164                }
1165            }
1166        }
1167
1168        for (;e.hasMoreElements();) {
1169            node=(MMObjectNode)e.nextElement();
1170            Enumeration f=tagger.Values("FIELDS").elements();
1171            for (;f.hasMoreElements();) {
1172                // hack hack this is way silly Strip needs to be fixed
1173
String JavaDoc fieldname=Strip.DoubleQuote((String JavaDoc)f.nextElement(),Strip.BOTH);
1174                result=node.getStringValue(fieldname);
1175                if (result!=null && !result.equals("null")) {
1176                    results+=" "+result;
1177                } else {
1178                    // this is weird
1179
}
1180            }
1181            results+="\n";
1182        }
1183        long end=(long)System.currentTimeMillis();
1184        //log.debug("MMbase -> doObject ("+type+")="+(end-begin)+" ms");
1185
return results;
1186    }
1187
1188    private Vector removeFunctions(Vector fields) {
1189        Vector results=new Vector();
1190        String JavaDoc fieldname,prefix;
1191        int posdot,posarc,posunder,pos;
1192        Enumeration f=fields.elements();
1193        for (;f.hasMoreElements();) {
1194            fieldname=Strip.DoubleQuote((String JavaDoc)f.nextElement(),Strip.BOTH);
1195            // get the first part (Example : episodes.);
1196
// we got two styles:
1197
// episodes.html_body
1198
// html(episodes.body)
1199
prefix="";
1200            posarc=fieldname.indexOf('(');
1201            if (posarc!=-1) {
1202                pos=fieldname.indexOf(')');
1203                String JavaDoc fieldname2 = fieldname.substring(posarc+1,pos);
1204                if (fieldname2 != null && fieldname2.length() > 0) {
1205                    results.addElement(fieldname2);
1206                }
1207            } else {
1208                posdot=fieldname.indexOf('.');
1209                if (posdot!=-1) {
1210                    prefix=fieldname.substring(0,posdot+1);
1211                    fieldname=fieldname.substring(posdot+1);
1212                }
1213                posunder=fieldname.indexOf('_');
1214                if (posunder!=-1) {
1215                    results.addElement(prefix+fieldname.substring(posunder+1));
1216                } else {
1217                    results.addElement(prefix+fieldname);
1218                }
1219            }
1220        }
1221        return results;
1222    }
1223
1224    public String JavaDoc getSearchAge(StringTokenizer tok) {
1225        String JavaDoc builder=tok.nextToken();
1226        log.debug("getSearchAge(): BUILDER="+builder);
1227        MMObjectBuilder bul=(MMObjectBuilder)mmb.getMMObject(builder);
1228        if (bul!=null) {
1229            return bul.getSearchAge();
1230        } else {
1231            return "30"; // ???
1232
}
1233    }
1234
1235    public MultilevelCacheHandler getMultilevelCacheHandler() {
1236        return multilevel_cache;
1237    }
1238
1239}
1240
Popular Tags