View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/admin/AdminUtils.java,v $
3    * $Revision: 1.79 $
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.template.MarkupLanguage;
58  import org.melati.util.HttpServletRequestCompat;
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 : HttpServletRequestCompat.getContextPath(melati.getRequest()),
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 creatioin 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   public String BottomURL(Table table, Melati melati) {
201     return  servletURL + "/" + logicalDatabase + 
202         "/" + table.getName() +
203         (melati.getObject() != null &&  
204                 melati.getObject().getTable() == table ? 
205                         "/" + melati.getObject().getTroid() 
206                         : "") + 
207         "/Bottom";
208   }
209   /**
210    * @return The Bottom URL.
211    */
212   public String BottomURL(Melati melati) {
213     String url =  servletURL + "/" + logicalDatabase + "/";
214     if (melati.getTable() != null)
215       url += melati.getTable().getName();
216     else 
217       url += getPrimaryDisplayTable(melati); 
218     if (melati.getObject() != null)
219       url += "/" + melati.getObject().getTroid();
220     url += "/Bottom";
221     return url;
222   }
223   /**
224    * @return The Left URL.
225    */
226   public String TableURL(Melati melati) {
227     return getURL(melati, "Table");
228   }
229   
230   /**
231    * @return The Right URL.
232    */
233   public String RecordURL(Persistent object) throws AccessPoemException {
234     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
235             + "/" + object.troid() + "/Record";
236   }
237 
238   /**
239    * @return The Right URL.
240    */
241   public String RecordURL(Persistent object, String returnTarget, String returnURL) throws AccessPoemException {
242     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
243             + "/" + object.troid() + "/Record" + 
244             "?returnTarget=" + returnTarget + 
245             "&returnURL=" + returnURL;
246   }
247 
248   /**
249    * @return The Right URL.
250    */
251   public String RecordURL(Melati melati) throws AccessPoemException {
252     return getURL(melati, "Record");
253   }
254 
255   /**
256    * @return The Primary Select URL.
257    */
258   public String PrimarySelectURL(Melati melati) {
259     return getURL(melati, "PrimarySelect");
260   }
261 
262   /**
263    * @return The Selection URL.
264    */
265   public String SelectionURL(Table table) {
266     return SelectionURL(table,"admin_record");
267   }
268   /**
269    * @return The Selection URL.
270    */
271   public String SelectionURL(Table table, String returnTarget) {
272     return SelectionURL(table, "admin_record", returnTarget);
273   }
274   /**
275    * @param table
276    * @param target
277    * @param returnTarget
278    * @return the url
279    */
280   public String SelectionURL(Table table, String target, String returnTarget) {
281     return servletURL + "/" + logicalDatabase + "/" + table.getName()
282             + "/Selection?" +
283             "target=" + target +  
284             "&returnTarget=" + returnTarget;
285   }
286   
287   /**
288    * Toggle the sort order of column.
289    * @return the same url with the toggle field added or removed
290    */
291   public String ToggledOrderSelectionURL(Melati melati, String field, String value) { 
292     String url = melati.sameURLWith(field,value);
293     String toggleField = "&" + field + "-toggle=true";
294     if (url.endsWith(toggleField))
295       return url.substring(0,url.length() - toggleField.length());
296     else 
297       return url + "&" + field + "-toggle=true";
298   }
299   
300   /**
301    * @param melati
302    * @return The Selection URL.
303    */
304   public String SelectionURL(Melati melati) {
305     return SelectionURL(melati,"admin_record");    
306   }
307 
308   /**
309    * @return The Selection URL.
310    */
311   public String SelectionURL(Melati melati, String returnTarget) {
312     return servletURL + "/" + 
313         logicalDatabase + "/" + 
314         melati.getTable().getName()
315           + "/Selection?" +
316           "target=admin_record" + 
317           "&returnTarget=" + (returnTarget == null ? "" : returnTarget) + 
318           (melati.getObject() == null ? 
319               "" : 
320               "&field_id=" + melati.getObject().troid());
321   }
322   
323   /**
324    * @return The Selection Right URL.
325    */
326   public String SelectionRightURL(Table table) {
327     return servletURL + "/" + logicalDatabase + "/" + table.getName()
328     + "/SelectionRight";
329   }
330 
331   /**
332    * @return The Navigation URL.
333    */
334   public String NavigationURL(Table table) {
335     return servletURL + "/" + logicalDatabase + "/" + table.getName()
336     + "/Navigation";
337   }
338   
339   /**
340    * @return The Edit Header URL.
341    */
342   public String EditHeaderURL(Melati melati) throws AccessPoemException {
343     if (melati.getObject() == null)
344       return getURL(melati, "blank");
345     else
346       return getURL(melati, "EditHeader");
347   }
348 
349   /**
350    * @return The Edit URL.
351    */
352   public String EditURL(Melati melati) throws AccessPoemException {
353     if (melati.getObject() == null)
354       return getURL(melati, "blank");
355     else
356       return getURL(melati, "Edit");
357   }
358   /**
359    * @return The Edit URL.
360    */
361   public String EditURL(Persistent object) throws AccessPoemException {
362     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
363             + "/" + object.troid() + "/Edit";
364   }
365 
366   /**
367    * @param melati
368    * @return the name of the Record Fields frame
369    */
370   public String EditFrameName(Melati melati) { 
371     String name = "admin_edit";
372     name += "_" + melati.getTable().getName();
373     if (melati.getObject() != null) 
374       name += "_" + melati.getObject().troid();
375     return name;
376   }
377   /**
378    * @return The Tree URL.
379    */
380   public String TreeURL(Persistent object) throws AccessPoemException {
381     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
382             + "/" + object.troid() + "/Tree";
383   }
384   
385   /**
386    * @return The Tree URL.
387    */
388   public String TreeURL(Table table) throws AccessPoemException {
389     return servletURL + "/" + logicalDatabase + "/" + table.getName()
390             +  "/Tree";
391   }
392   
393 
394   /**
395    * @return The Add URL.
396    */
397   public String AddURL(Table table) throws AccessPoemException {
398     return servletURL
399             + "/"
400             + logicalDatabase
401             + "/" 
402             + table.getName() 
403             + "/" 
404             + "Add";
405   }
406 
407   /**
408    * @return The Popup URL.
409    */
410   public String PopUpURL(Table table) {
411     return servletURL + "/" + logicalDatabase + "/" + table.getName() + "/PopUp";
412   }
413   
414   /**
415    * @return The Selection Window URL.
416    */
417   public String SelectionWindowURL(Table table) {
418     return servletURL + "/" + logicalDatabase + "/" + table.getName()
419             + "/SelectionWindow?target=";
420   }
421 
422   /**
423    * @return The Selection Window Primary Select URL.
424    */
425   public String SelectionWindowPrimarySelectURL(Table table) {
426     return servletURL + "/" + logicalDatabase + "/" + table.getName()
427             + "/SelectionWindowPrimarySelect";
428   }
429 
430   /**
431    * @return The Selection Window Selection URL.
432    */
433   public String SelectionWindowSelectionURL(Table table) {
434     return servletURL + "/" + logicalDatabase + "/" + table.getName()
435             + "/SelectionWindowSelection";
436   }
437   
438   /**
439    * @return The Status URL.
440    */
441   public String StatusURL() {
442     return contextPath + "/org.melati.admin.Status/" + logicalDatabase;
443   }
444   
445   /**
446    * @return The Session Analysis URL.
447    */
448   public String SessionURL() {
449     return contextPath + "/org.melati.test.SessionAnalysisServlet";
450   }
451   
452   /**
453    * @return The URL for DSD generation. 
454    */
455   public String DsdURL() {
456     return servletURL + "/" + logicalDatabase + "/DSD";
457   }
458   
459   /**
460    * In an insert situation we will not have a Troid, so cannot pass it through.
461    * If your upload handler depends on having a persistent, then you should
462    * override your upload template so that it prevents uploading in an insert
463    * situation.
464    * 
465    * @param table table object belongs to
466    * @param object the Persistent we are dealing with
467    * @param field the upload field
468    * @return Upload Url
469    */
470   public String UploadURL(Table table, Persistent object, Field field) {
471     return upload(table, object) + "/Upload?field=" + field.getName();
472   }
473   
474   /**
475    * Upload URL.
476    * 
477    * @param table table object belongs to
478    * @param object the Persistent we are dealing with
479    * @param field the upload field
480    * @return Upload done URL
481    */
482   public String UploadHandlerURL(Table table, Persistent object, String field) {
483     return upload(table, object) + "/UploadDone?field=" + field;
484   }
485   private String upload(Table table, Persistent object) {
486     String url = servletURL + "/" + logicalDatabase + "/" + table.getName();
487     if (object != null)
488       url += "/" + object.troid();
489     return url;
490   }
491   
492  
493   /**
494    * Render the specials directly to the output.
495    *  
496    * FIXME No longer rendering directly
497    * 
498    * @param melati the Melati
499    * @param ml The MarkupLanguage we are using
500    * @param object a Persistent to render the specials of 
501    * @return an empty String
502    * @throws Exception maybe
503    */
504   public String specialFacilities(Melati melati, MarkupLanguage ml,
505           Persistent object) throws Exception {
506   if (object instanceof AdminSpecialised)
507     melati.getTemplateEngine().expandTemplate(melati.getWriter(),
508           ((AdminSpecialised) object).adminSpecialFacilities(melati, ml),
509           melati.getTemplateContext());
510   return "";
511   /*
512   if (object instanceof AdminSpecialised)
513       return melati.getTemplateEngine().expandedTemplate(
514           melati.getTemplateEngine().template(
515               ((AdminSpecialised) object).adminSpecialFacilities(melati, ml)),
516               melati.getTemplateContext());
517     else 
518       return "";
519     */
520   }
521 
522   /**
523    * @return Defaults to /MelatiStatic/admin
524    */
525   public String getStaticURL() {
526     return staticURL;
527   }
528 
529   /**
530    *  Create a tree. 
531    * @param node  a tree node
532    * @return a tree with node as its root
533    */
534   public JSStaticTree createTree(Treeable node) {
535     return new JSStaticTree(new Tree(node), getStaticURL());
536   }
537   
538   /**
539    *  Create a tree. 
540    * @param table  the table to tree 
541    * @return a tree with node as its root
542    */
543   public JSStaticTree createForest(Table table) {
544     Object[] all = ArrayUtils.arrayOf(table.selection());
545     Treeable[] members = new Treeable[all.length];
546     Hashtable hasParent = new Hashtable();
547     for (int i = 0; i < all.length; i++) {
548       members[i] = (Treeable)all[i];
549       if (hasParent.get(all[i]) == null){ 
550         Treeable[] kids = ((Treeable)all[i]).getChildren();
551         for (int j = 0; j < kids.length; j++)
552           hasParent.put(kids[j], Boolean.TRUE);
553       }
554     }
555     int count = 0;
556     for (int i = 0; i < all.length; i++) {
557       if (hasParent.get(members[i]) == null){ 
558         count++;
559       }
560     }
561     Treeable[] roots = new Treeable[count];
562     int j = 0;
563     for (int i = 0; i < all.length; i++) {
564       if (hasParent.get(members[i]) == null){
565         roots[j] = members[i];
566         j++;
567       }
568     }
569     return new JSStaticTree(roots, getStaticURL());
570   }
571 
572   /**
573    * @param qualifiedName
574    * @return text followuing the last dot
575    */
576   public static String simpleName(String qualifiedName) { 
577     return qualifiedName.substring(
578         qualifiedName.lastIndexOf('.') != -1 ?
579             qualifiedName.lastIndexOf('.') + 1 : 
580             0,
581         qualifiedName.length());
582   }
583 }