View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/admin/AdminUtils.java,v $
3    * $Revision: 1.82 $
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.HttpServletRequestCompat;
60  import org.melati.util.JSStaticTree;
61  import org.melati.util.Tree;
62  
63  
64  /**
65   * A utility object for placing in a <code>ServletTemplateContext</code>.
66   */
67  public class AdminUtils {
68    
69    private String contextPath;
70    private String servletURL;
71    private String staticURL;
72    private String logicalDatabase;
73    
74    /**
75     *  Constructor. 
76     */
77    public AdminUtils(Melati melati) {
78      this(melati.getRequest() == null ? null : HttpServletRequestCompat.getContextPath(melati.getRequest()),
79           melati.getRequest() == null ? null : melati.getRequest().getServletPath(),
80           melati.getConfig().getStaticURL() ,
81           melati.getPoemContext().getLogicalDatabase());    
82    }
83  
84    /**
85     *  Constructor. 
86     */
87    private AdminUtils(String contextPath, String servlet, 
88                      String staticURL, String logicalDatabase) {
89      this.contextPath = contextPath;
90      this.servletURL = contextPath + servlet;
91      this.staticURL = staticURL;
92      this.logicalDatabase = logicalDatabase;
93      // HACK if we are using 2.0 Servlet API then zone is
94      // included in servlet and contextPath is empty
95      if (contextPath == "") {
96        this.contextPath = servlet.substring(0, servlet.lastIndexOf("/"));
97      }
98    }
99    
100   /**
101    * @return the name of the default table to display  
102    */
103   public static String getPrimaryDisplayTable(Melati melati) { 
104     if (Admin.getPrimaryDisplayTable() == null) 
105       Admin.setPrimaryDisplayTable(melati.getDatabase().
106           getSettingTable().get(Admin.class.getName() + ".PrimaryDisplayTable"));
107     if (Admin.getPrimaryDisplayTable() == null)
108       Admin.setPrimaryDisplayTable("columninfo");
109     return Admin.getPrimaryDisplayTable();
110   }
111   
112   /**
113    * @param melati to get db from
114    * @return the stylesheet for screen media  
115    */
116   public String getScreenStylesheetURL(Melati melati) {
117     if (Admin.getScreenStylesheetURL() == null) 
118       Admin.setScreenStylesheetURL(melati.getDatabase().
119           getSettingTable().get(Admin.class.getName() + ".ScreenStylesheetURL"));
120     if (Admin.getScreenStylesheetURL() == null)
121       Admin.setScreenStylesheetURL("/admin.css");
122     return staticURL + Admin.getScreenStylesheetURL();
123   }
124   /**
125    * @return the settings table setup url
126    */
127   public String getSetupURL() {
128     return servletURL + "/" + logicalDatabase + 
129         "/setting/setup";
130   }
131   
132   
133   /**
134    * Check if setting in db, provide default if not, do not 
135    * write default to db. 
136    * 
137    * @param melati to get db from
138    * @return the homepage URL for this databse  
139    */
140   public String getHomepageURL(Melati melati) {
141     if (Admin.getHomepageURL() == null) 
142       Admin.setHomepageURL(melati.getDatabase().
143           getSettingTable().get(Admin.class.getName() + ".HomepageURL"));
144     if (Admin.getHomepageURL() == null)
145       Admin.setHomepageURL("http://www.melati.org/");
146     return Admin.getHomepageURL();
147   }
148   
149   /**
150    * @param melati the melati
151    * @param name of template
152    * @return name prepended with ldb, table and troid if not null
153    */
154   public String getURL(Melati melati, String name) { 
155     String url = servletURL + "/" + logicalDatabase;
156     if (melati.getTable() != null)
157       url += "/" + melati.getTable().getName();
158     if (melati.getObject() != null)
159       url += "/" + melati.getObject().getTroid();
160     return url + "/" + name;
161   }
162   /**
163    * @return name prepended with ldb and table name
164    */
165   public String getURL(Table table, String name) { 
166     String url = servletURL + "/" + logicalDatabase;
167     url += "/" + table.getName();
168     return url + "/" + name;
169   }
170   
171   
172   /** @return The Main URL. */
173   public String MainURL(String ld) {
174     String url = servletURL + "/" + ld;
175     return url + "/Main";
176   }
177   /** @return The Main URL. */
178   public String MainURL(Melati melati) {
179     return getURL(melati, "Main");
180   }
181   /** @return The Main URL after deletion of a tableinfo */
182   public String MainURL(Table table) {
183     return getURL(table, "Main");
184   }
185   /** @return The Main URL after creatioin of a tableinfo */
186   public String MainURL(Table table,Persistent p) {
187     String url = servletURL + "/" + logicalDatabase;
188     url += "/" + table.getName();
189     url += "/" + p.troid();
190     return url + "/" + "Main";
191  }
192   
193   /** @return The Top URL. */
194   public String TopURL(Melati melati) {
195     return getURL(melati, "Top");
196   }
197   
198   /**
199    * @return The Bottom URL.
200    */
201   public String BottomURL(Table table, Melati melati) {
202     return  servletURL + "/" + logicalDatabase + 
203         "/" + table.getName() +
204         (melati.getObject() != null &&  
205                 melati.getObject().getTable() == table ? 
206                         "/" + melati.getObject().getTroid() 
207                         : "") + 
208         "/Bottom";
209   }
210   /**
211    * @return The Bottom URL.
212    */
213   public String BottomURL(Melati melati) {
214     String url =  servletURL + "/" + logicalDatabase + "/";
215     if (melati.getTable() != null)
216       url += melati.getTable().getName();
217     else 
218       url += getPrimaryDisplayTable(melati); 
219     if (melati.getObject() != null)
220       url += "/" + melati.getObject().getTroid();
221     url += "/Bottom";
222     return url;
223   }
224   /**
225    * @return The Left URL.
226    */
227   public String TableURL(Melati melati) {
228     return getURL(melati, "Table");
229   }
230   
231   /**
232    * @return The Right URL.
233    */
234   public String RecordURL(Persistent object) throws AccessPoemException {
235     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
236             + "/" + object.troid() + "/Record";
237   }
238 
239   /**
240    * @return The Right URL.
241    */
242   public String RecordURL(Persistent object, String returnTarget, String returnURL) throws AccessPoemException {
243     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
244             + "/" + object.troid() + "/Record" + 
245             "?returnTarget=" + returnTarget + 
246             "&returnURL=" + returnURL;
247   }
248 
249   /**
250    * @return The Right URL.
251    */
252   public String RecordURL(Melati melati) throws AccessPoemException {
253     return getURL(melati, "Record");
254   }
255 
256   /**
257    * @return The Primary Select URL.
258    */
259   public String PrimarySelectURL(Melati melati) {
260     return getURL(melati, "PrimarySelect");
261   }
262 
263   /**
264    * @return The Selection URL.
265    */
266   public String SelectionURL(Table table) {
267     return SelectionURL(table,"admin_record");
268   }
269   /**
270    * @return The Selection URL.
271    */
272   public String SelectionURL(Table table, String returnTarget) {
273     return SelectionURL(table, "admin_record", returnTarget);
274   }
275   /**
276    * @param table
277    * @param target
278    * @param returnTarget
279    * @return the url
280    */
281   public String SelectionURL(Table table, String target, String returnTarget) {
282     return servletURL + "/" + logicalDatabase + "/" + table.getName()
283             + "/Selection?" +
284             "target=" + target +  
285             "&returnTarget=" + returnTarget;
286   }
287   
288   /**
289    * Toggle the sort order of column.
290    * @return the same url with the toggle field added or removed
291    */
292   public String ToggledOrderSelectionURL(Melati melati, String field, String value) { 
293     String url = melati.sameURLWith(field,value);
294     String toggleField = "&" + field + "-toggle=true";
295     if (url.endsWith(toggleField))
296       return url.substring(0,url.length() - toggleField.length());
297     else 
298       return url + "&" + field + "-toggle=true";
299   }
300   
301   /**
302    * @param melati
303    * @return The Selection URL.
304    */
305   public String SelectionURL(Melati melati) {
306     return SelectionURL(melati,"admin_record");    
307   }
308 
309   /**
310    * @return The Selection URL.
311    */
312   public String SelectionURL(Melati melati, String returnTarget) {
313     return servletURL + "/" + 
314         logicalDatabase + "/" + 
315         melati.getTable().getName()
316           + "/Selection?" +
317           "target=admin_record" + 
318           "&returnTarget=" + (returnTarget == null ? "" : returnTarget) + 
319           (melati.getObject() == null ? 
320               "" : 
321               "&field_id=" + melati.getObject().troid());
322   }
323   
324   /**
325    * @return The Selection Right URL.
326    */
327   public String SelectionRightURL(Table table) {
328     return servletURL + "/" + logicalDatabase + "/" + table.getName()
329     + "/SelectionRight";
330   }
331 
332   /**
333    * @return The Navigation URL.
334    */
335   public String NavigationURL(Table table) {
336     return servletURL + "/" + logicalDatabase + "/" + table.getName()
337     + "/Navigation";
338   }
339   
340   /**
341    * @return The Edit Header URL.
342    */
343   public String EditHeaderURL(Melati melati) throws AccessPoemException {
344     if (melati.getObject() == null)
345       return getURL(melati, "blank");
346     else
347       return getURL(melati, "EditHeader");
348   }
349 
350   /**
351    * @return The Edit URL.
352    */
353   public String EditURL(Melati melati) throws AccessPoemException {
354     if (melati.getObject() == null)
355       return getURL(melati, "blank");
356     else
357       return getURL(melati, "Edit");
358   }
359   /**
360    * @return The Edit URL.
361    */
362   public String EditURL(Persistent object) throws AccessPoemException {
363     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
364             + "/" + object.troid() + "/Edit";
365   }
366 
367   /**
368    * @param melati
369    * @return the name of the Record Fields frame
370    */
371   public String EditFrameName(Melati melati) { 
372     String name = "admin_edit";
373     name += "_" + melati.getTable().getName();
374     if (melati.getObject() != null) 
375       name += "_" + melati.getObject().troid();
376     return name;
377   }
378   /**
379    * @return The Tree URL.
380    */
381   public String TreeURL(Persistent object) throws AccessPoemException {
382     return servletURL + "/" + logicalDatabase + "/" + object.getTable().getName()
383             + "/" + object.troid() + "/Tree";
384   }
385   
386   /**
387    * @return The Tree URL.
388    */
389   public String TreeURL(Table table) throws AccessPoemException {
390     return servletURL + "/" + logicalDatabase + "/" + table.getName()
391             +  "/Tree";
392   }
393   
394 
395   /**
396    * @return The Add URL.
397    */
398   public String AddURL(Table table) throws AccessPoemException {
399     return servletURL
400             + "/"
401             + logicalDatabase
402             + "/" 
403             + table.getName() 
404             + "/" 
405             + "Add";
406   }
407 
408   /**
409    * @return The Popup URL.
410    */
411   public String PopUpURL(Table table) {
412     return servletURL + "/" + logicalDatabase + "/" + table.getName() + "/PopUp";
413   }
414   
415   /**
416    * @return The Selection Window URL.
417    */
418   public String SelectionWindowURL(Table table) {
419     return servletURL + "/" + logicalDatabase + "/" + table.getName()
420             + "/SelectionWindow?target=";
421   }
422 
423   /**
424    * @return The Selection Window Primary Select URL.
425    */
426   public String SelectionWindowPrimarySelectURL(Table table) {
427     return servletURL + "/" + logicalDatabase + "/" + table.getName()
428             + "/SelectionWindowPrimarySelect";
429   }
430 
431   /**
432    * @return The Selection Window Selection URL.
433    */
434   public String SelectionWindowSelectionURL(Table table) {
435     return servletURL + "/" + logicalDatabase + "/" + table.getName()
436             + "/SelectionWindowSelection";
437   }
438   
439   /**
440    * @return The Status URL.
441    */
442   public String StatusURL() {
443     return contextPath + "/org.melati.admin.Status/" + logicalDatabase;
444   }
445   
446   /**
447    * @return The Session Analysis URL.
448    */
449   public String SessionURL() {
450     return contextPath + "/org.melati.test.SessionAnalysisServlet";
451   }
452   
453   /**
454    * @return The URL for DSD generation. 
455    */
456   public String DsdURL() {
457     return servletURL + "/" + logicalDatabase + "/DSD";
458   }
459   
460   /**
461    * In an insert situation we will not have a Troid, so cannot pass it through.
462    * If your upload handler depends on having a persistent, then you should
463    * override your upload template so that it prevents uploading in an insert
464    * situation.
465    * 
466    * @param table table object belongs to
467    * @param object the Persistent we are dealing with
468    * @param field the upload field
469    * @return Upload Url
470    */
471   public String UploadURL(Table table, Persistent object, Field field) {
472     return upload(table, object) + "/Upload?field=" + field.getName();
473   }
474   
475   /**
476    * Upload URL.
477    * 
478    * @param table table object belongs to
479    * @param object the Persistent we are dealing with
480    * @param field the upload field
481    * @return Upload done URL
482    */
483   public String UploadHandlerURL(Table table, Persistent object, String field) {
484     return upload(table, object) + "/UploadDone?field=" + field;
485   }
486   private String upload(Table table, Persistent object) {
487     String url = servletURL + "/" + logicalDatabase + "/" + table.getName();
488     if (object != null)
489       url += "/" + object.troid();
490     return url;
491   }
492   
493  
494   /**
495    * Render the specials directly to the output.
496    *  
497    * FIXME No longer rendering directly
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 hasParent = new Hashtable();
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 followuing 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 }