View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/admin/AdminUtils.java,v $
3    * $Revision: 1.86 $
4    *
5    * Copyright (C) 2000 William Chesters
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     William Chesters <williamc At paneris.org>
42   *     http://paneris.org/~williamc
43   *     Obrechtstraat 114, 2517VX Den Haag, The Netherlands
44   */
45  package org.melati.admin;
46  
47  
48  import java.util.Hashtable;
49  
50  import org.melati.Melati;
51  import org.melati.poem.AccessPoemException;
52  import org.melati.poem.Field;
53  import org.melati.poem.Persistent;
54  import org.melati.poem.Table;
55  import org.melati.poem.Treeable;
56  import org.melati.poem.util.ArrayUtils;
57  import org.melati.poem.util.StringUtils;
58  import org.melati.template.MarkupLanguage;
59  import org.melati.util.JSStaticTree;
60  import org.melati.util.Tree;
61  
62  
63  /**
64   * A utility object for placing in a <code>ServletTemplateContext</code>.
65   */
66  public class AdminUtils {
67    
68    private String contextPath;
69    private String servletURL;
70    private String staticURL;
71    private String logicalDatabase;
72    
73    /**
74     *  Constructor. 
75     */
76    public AdminUtils(Melati melati) {
77      this(melati.getRequest() == null ? null : melati.getRequest().getContextPath(),
78           melati.getRequest() == null ? null : melati.getRequest().getServletPath(),
79           melati.getConfig().getStaticURL() ,
80           melati.getPoemContext().getLogicalDatabase());    
81    }
82  
83    /**
84     *  Constructor. 
85     */
86    private AdminUtils(String contextPath, String servlet, 
87                      String staticURL, String logicalDatabase) {
88      this.contextPath = contextPath;
89      this.servletURL = contextPath + servlet;
90      this.staticURL = staticURL;
91      this.logicalDatabase = logicalDatabase;
92      // HACK if we are using 2.0 Servlet API then zone is
93      // included in servlet and contextPath is empty
94      if (contextPath == "") {
95        this.contextPath = servlet.substring(0, servlet.lastIndexOf("/"));
96      }
97    }
98    
99    /**
100    * @return the name of the default table to display  
101    */
102   public static String getPrimaryDisplayTable(Melati melati) { 
103     if (Admin.getPrimaryDisplayTable() == null) 
104       Admin.setPrimaryDisplayTable(melati.getDatabase().
105           getSettingTable().get(Admin.class.getName() + ".PrimaryDisplayTable"));
106     if (Admin.getPrimaryDisplayTable() == null)
107       Admin.setPrimaryDisplayTable("columninfo");
108     return Admin.getPrimaryDisplayTable();
109   }
110   
111   /**
112    * @param melati to get db from
113    * @return the stylesheet for screen media  
114    */
115   public String getScreenStylesheetURL(Melati melati) {
116     if (Admin.getScreenStylesheetURL() == null) 
117       Admin.setScreenStylesheetURL(melati.getDatabase().
118           getSettingTable().get(Admin.class.getName() + ".ScreenStylesheetURL"));
119     if (Admin.getScreenStylesheetURL() == null)
120       Admin.setScreenStylesheetURL("/admin.css");
121     return staticURL + Admin.getScreenStylesheetURL();
122   }
123   /**
124    * @return the settings table setup url
125    */
126   public String getSetupURL() {
127     return servletURL + "/" + logicalDatabase + 
128         "/setting/setup";
129   }
130   
131   
132   /**
133    * Check if setting in db, provide default if not, do not 
134    * write default to db. 
135    * 
136    * @param melati to get db from
137    * @return the homepage URL for this databse  
138    */
139   public String getHomepageURL(Melati melati) {
140     if (Admin.getHomepageURL() == null) 
141       Admin.setHomepageURL(melati.getDatabase().
142           getSettingTable().get(Admin.class.getName() + ".HomepageURL"));
143     if (Admin.getHomepageURL() == null)
144       Admin.setHomepageURL("http://www.melati.org/");
145     return Admin.getHomepageURL();
146   }
147   
148   /**
149    * @param melati the melati
150    * @param name of template
151    * @return name prepended with ldb, table and troid if not null
152    */
153   public String getURL(Melati melati, String name) { 
154     String url = servletURL + "/" + logicalDatabase;
155     if (melati.getTable() != null)
156       url += "/" + melati.getTable().getName();
157     if (melati.getObject() != null)
158       url += "/" + melati.getObject().getTroid();
159     return url + "/" + name;
160   }
161   /**
162    * @return name prepended with ldb and table name
163    */
164   public String getURL(Table table, String name) { 
165     String url = servletURL + "/" + logicalDatabase;
166     url += "/" + table.getName();
167     return url + "/" + name;
168   }
169   
170   
171   /** @return The Main URL. */
172   public String MainURL(String ld) {
173     String url = servletURL + "/" + ld;
174     return url + "/Main";
175   }
176   /** @return The Main URL. */
177   public String MainURL(Melati melati) {
178     return getURL(melati, "Main");
179   }
180   /** @return The Main URL after deletion of a tableinfo */
181   public String MainURL(Table table) {
182     return getURL(table, "Main");
183   }
184   /** @return The Main URL after creation of a tableinfo */
185   public String MainURL(Table table,Persistent p) {
186     String url = servletURL + "/" + logicalDatabase;
187     url += "/" + table.getName();
188     url += "/" + p.troid();
189     return url + "/" + "Main";
190  }
191   
192   /** @return The Top URL. */
193   public String TopURL(Melati melati) {
194     return getURL(melati, "Top");
195   }
196   
197   /**
198    * @return The Bottom URL.
199    */
200   /*
201    * Do not think this is used
202   public String BottomURL(Table table, Melati melati) {
203     return  servletURL + "/" + logicalDatabase + 
204         "/" + table.getName() +
205         (melati.getObject() != null &&  
206                 melati.getObject().getTable() == table ? 
207                         "/" + melati.getObject().getTroid() 
208                         : "") + 
209         "/Bottom";
210   }
211   */
212   /**
213    * @return The Bottom URL.
214    */
215   public String BottomURL(Melati melati) {
216     String url =  servletURL + "/" + logicalDatabase + "/";
217     if (melati.getTable() != null)
218       url += melati.getTable().getName();
219     else 
220       url += getPrimaryDisplayTable(melati); 
221     if (melati.getObject() != null)
222       url += "/" + melati.getObject().getTroid();
223     url += "/Bottom";
224     return url;
225   }
226   /**
227    * @return The Left URL.
228    */
229   public String TableURL(Table table) {
230     return getURL(table, "Table");
231   }
232   
233   /**
234    * @return The Right URL.
235    */
236   public String RecordURL(Persistent object) throws AccessPoemException {
237     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
238             + "/" + object.troid() + "/Record";
239   }
240 
241   /**
242    * @return The Right URL.
243    */
244   public String RecordURL(Persistent object, String returnTarget, String returnURL) throws AccessPoemException {
245     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
246             + "/" + object.troid() + "/Record" + 
247             "?returnTarget=" + returnTarget + 
248             "&returnURL=" + returnURL;
249   }
250 
251   /**
252    * @return The Right URL.
253    */
254   public String RecordURL(Melati melati) throws AccessPoemException {
255     return getURL(melati, "Record");
256   }
257 
258   /**
259    * @return The Primary Select URL.
260    */
261   public String PrimarySelectURL(Melati melati) {
262     return getURL(melati, "PrimarySelect");
263   }
264 
265   /**
266    * @return The Selection URL.
267    */
268   public String SelectionURL(Table table) {
269     return SelectionURL(table,"admin_record");
270   }
271   /**
272    * @return The Selection URL.
273    */
274   public String SelectionURL(Table table, String returnTarget) {
275     return SelectionURL(table, "admin_record", returnTarget);
276   }
277   /**
278    * @param table
279    * @param targetPane
280    * @param returnTarget
281    * @return the url
282    */
283   public String SelectionURL(Table table, String targetPane, String returnTarget) {
284     return servletURL + "/" + logicalDatabase + "/" + table.getName()
285             + "/Selection?" +
286             "target=" + targetPane +  
287             "&returnTarget=" + returnTarget;
288   }
289   
290   /**
291    * Toggle the sort order of column.
292    * @return the same url with the toggle field added or removed
293    */
294   public String ToggledOrderSelectionURL(Melati melati, String field, String value) { 
295     String url = melati.sameURLWith(field,value);
296     String toggleField = "&" + field + "-toggle=true";
297     if (url.endsWith(toggleField))
298       return url.substring(0,url.length() - toggleField.length());
299     else 
300       return url + "&" + field + "-toggle=true";
301   }
302   
303   /**
304    * @param melati
305    * @return The Selection URL.
306    */
307   public String SelectionURL(Melati melati) {
308     return SelectionURL(melati,"admin_record");    
309   }
310 
311   /**
312    * @return The Selection URL.
313    */
314   public String SelectionURL(Melati melati, String returnTarget) {
315     return servletURL + "/" + 
316         logicalDatabase + "/" + 
317         melati.getTable().getName()
318           + "/Selection?" +
319           "target=admin_record" + 
320           "&returnTarget=" + (returnTarget == null ? "" : returnTarget) + 
321           (melati.getObject() == null ? 
322               "" : 
323               "&field_id=" + melati.getObject().troid());
324   }
325   
326   /**
327    * @return The Selection Right URL.
328    */
329   public String SelectionRightURL(Table table) {
330     return servletURL + "/" + logicalDatabase + "/" + table.getName()
331     + "/SelectionRight";
332   }
333 
334   /**
335    * @return The Navigation URL.
336    */
337   public String NavigationURL(Table table) {
338     return servletURL + "/" + logicalDatabase + "/" + table.getName()
339     + "/Navigation";
340   }
341   
342   /**
343    * @return The Edit Header URL.
344    */
345   public String EditHeaderURL(Melati melati) throws AccessPoemException {
346     if (melati.getObject() == null)
347       return getURL(melati, "blank");
348     else
349       return getURL(melati, "EditHeader");
350   }
351 
352   /**
353    * @return The Edit URL.
354    */
355   public String EditURL(Melati melati) throws AccessPoemException {
356     if (melati.getObject() == null)
357       return getURL(melati, "blank");
358     else
359       return getURL(melati, "Edit");
360   }
361   /**
362    * @return The Edit URL.
363    */
364   public String EditURL(Persistent object) throws AccessPoemException {
365     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
366             + "/" + object.troid() + "/Edit";
367   }
368 
369   /**
370    * @param melati
371    * @return the name of the Record Fields frame
372    */
373   public String EditFrameName(Melati melati) { 
374     String name = "admin_edit";
375     name += "_" + melati.getTable().getName();
376     if (melati.getObject() != null) 
377       name += "_" + melati.getObject().troid();
378     return name;
379   }
380   /**
381    * @return The Tree URL.
382    */
383   public String TreeURL(Persistent object) throws AccessPoemException {
384     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
385             + "/" + object.troid() + "/Tree";
386   }
387   
388   /**
389    * @return The Tree URL.
390    */
391   public String TreeURL(Table table) throws AccessPoemException {
392     return servletURL + "/" + logicalDatabase + "/" + table.getName()
393             +  "/Tree";
394   }
395   
396 
397   /**
398    * @return The Add URL.
399    */
400   public String AddURL(Table table) throws AccessPoemException {
401     return servletURL
402             + "/"
403             + logicalDatabase
404             + "/" 
405             + table.getName() 
406             + "/" 
407             + "Add";
408   }
409 
410   /**
411    * @return The Popup URL.
412    */
413   public String PopUpURL(Table table) {
414     return servletURL + "/" + logicalDatabase + "/" + table.getName() + "/PopUp";
415   }
416   
417   /**
418    * @return The Selection Window URL.
419    */
420   public String SelectionWindowURL(Table table) {
421     return servletURL + "/" + logicalDatabase + "/" + table.getName()
422             + "/SelectionWindow?target=";
423   }
424 
425   /**
426    * @return The Selection Window Primary Select URL.
427    */
428   public String SelectionWindowPrimarySelectURL(Table table) {
429     return servletURL + "/" + logicalDatabase + "/" + table.getName()
430             + "/SelectionWindowPrimarySelect";
431   }
432 
433   /**
434    * @return The Selection Window Selection URL.
435    */
436   public String SelectionWindowSelectionURL(Table table) {
437     return servletURL + "/" + logicalDatabase + "/" + table.getName()
438             + "/SelectionWindowSelection";
439   }
440   
441   /**
442    * @return The Status URL.
443    */
444   public String StatusURL() {
445     return contextPath + "/org.melati.admin.Status/" + logicalDatabase;
446   }
447   
448   /**
449    * @return The Session Analysis URL.
450    */
451   public String SessionURL() {
452     return contextPath + "/org.melati.test.SessionAnalysisServlet";
453   }
454   
455   /**
456    * @return The URL for DSD generation. 
457    */
458   public String DsdURL() {
459     return servletURL + "/" + logicalDatabase + "/DSD";
460   }
461   
462   /**
463    * In an insert situation we will not have a Troid, so cannot pass it through.
464    * If your upload handler depends on having a persistent, then you should
465    * override your upload template so that it prevents uploading in an insert
466    * situation.
467    * 
468    * @param table table object belongs to
469    * @param object the Persistent we are dealing with
470    * @param field the upload field
471    * @return Upload Url
472    */
473   public String UploadURL(Table table, Persistent object, Field field) {
474     return upload(table, object) + "/Upload?field=" + field.getName();
475   }
476   
477   /**
478    * Upload URL.
479    * 
480    * @param table table object belongs to
481    * @param object the Persistent we are dealing with
482    * @param field the upload field
483    * @return Upload done URL
484    */
485   public String UploadHandlerURL(Table table, Persistent object, String field) {
486     return upload(table, object) + "/UploadDone?field=" + field;
487   }
488   private String upload(Table table, Persistent object) {
489     String url = servletURL + "/" + logicalDatabase + "/" + table.getName();
490     if (object != null)
491       url += "/" + object.troid();
492     return url;
493   }
494   
495  
496   /**
497    * Render the specials directly to the output.
498    *  
499    * @param melati the Melati
500    * @param ml The MarkupLanguage we are using
501    * @param object a Persistent to render the specials of 
502    * @return an empty String
503    * @throws Exception maybe
504    */
505   public String specialFacilities(Melati melati, MarkupLanguage ml,
506           Persistent object) throws Exception {
507   if (object instanceof AdminSpecialised)
508     melati.getTemplateEngine().expandTemplate(melati.getWriter(),
509           ((AdminSpecialised) object).adminSpecialFacilities(melati, ml),
510           melati.getTemplateContext());
511   return "";
512   /*
513   if (object instanceof AdminSpecialised)
514       return melati.getTemplateEngine().expandedTemplate(
515           melati.getTemplateEngine().template(
516               ((AdminSpecialised) object).adminSpecialFacilities(melati, ml)),
517               melati.getTemplateContext());
518     else 
519       return "";
520     */
521   }
522 
523   /**
524    * @return Defaults to /MelatiStatic/admin
525    */
526   public String getStaticURL() {
527     return staticURL;
528   }
529 
530   /**
531    *  Create a tree. 
532    * @param node  a tree node
533    * @return a tree with node as its root
534    */
535   public JSStaticTree createTree(Treeable node) {
536     return new JSStaticTree(new Tree(node), getStaticURL());
537   }
538   
539   /**
540    *  Create a forest of trees. 
541    * @param table  the table to tree 
542    * @return a tree with node as its root
543    */
544   public JSStaticTree createForest(Table table) {
545     Object[] all = ArrayUtils.arrayOf(table.selection());
546     Hashtable<Treeable, Boolean> hasParent = new Hashtable<Treeable, Boolean>();
547     for (int i = 0; i < all.length; i++) {
548       if (hasParent.get(all[i]) == null) { 
549         Treeable[] kids = ((Treeable)all[i]).getChildren();
550         for (int j = 0; j < kids.length; j++)
551           hasParent.put(kids[j], Boolean.TRUE);
552       }
553     }
554     int count = 0;
555     for (int i = 0; i < all.length; i++) {
556       if (hasParent.get(all[i]) == null){ 
557         count++;
558       }
559     }
560     Treeable[] roots = new Treeable[count];
561     int j = 0;
562     for (int i = 0; i < all.length; i++) {
563       if (hasParent.get(all[i]) == null) {
564         roots[j] = (Treeable)all[i];
565         j++;
566       }
567     }
568     return new JSStaticTree(roots, getStaticURL());
569   }
570 
571   /**
572    * @param qualifiedName
573    * @return text following the last dot
574    */
575   public static String simpleName(String qualifiedName) { 
576     return qualifiedName.substring(
577         qualifiedName.lastIndexOf('.') != -1 ?
578             qualifiedName.lastIndexOf('.') + 1 : 
579             0,
580         qualifiedName.length());
581   }
582   
583   /**
584    * @param in the String to escape
585    * @return the escaped String
586    */
587   public static String csvEscaped(String in) { 
588     StringBuffer b = new StringBuffer();
589     StringUtils.appendEscaped(b, in, '"', '"');
590     return b.toString();
591   }
592 }