KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > idaremedia > antx > print > PrinterMapping


1 /**
2  * $Id: PrinterMapping.java 180 2007-03-15 12:56:38Z ssmc $
3  * Copyright 2002-2005 iDare Media, Inc. All rights reserved.
4  *
5  * Originally written by iDare Media, Inc. for release into the public domain. This
6  * library, source form and binary form, is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation; either version 2.1 of the License, or (at your option) any
9  * later version.<p>
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU LGPL (GNU Lesser General Public License) for more details.<p>
14  *
15  * You should have received a copy of the GNU Lesser General Public License along with this
16  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite
17  * 330, Boston, MA 02111-1307 USA. The LGPL can be found online at
18  * http://www.fsf.org/copyleft/lesser.html<p>
19  *
20  * This product has been influenced by several projects within the open-source community.
21  * The JWare developers wish to acknowledge the open-source community's support. For more
22  * information regarding the open-source products used within JWare, please visit the
23  * JWare website.
24  *----------------------------------------------------------------------------------------*
25  * WEBSITE- http://www.jware.info EMAIL- inquiries@jware.info
26  *----------------------------------------------------------------------------------------*
27  **/

28
29 package com.idaremedia.antx.print;
30
31 import java.io.File JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.net.MalformedURLException JavaDoc;
34 import java.net.URL JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.HashSet JavaDoc;
38 import java.util.Properties JavaDoc;
39 import java.util.Set JavaDoc;
40
41 import org.apache.tools.ant.BuildException;
42 import org.apache.tools.ant.Project;
43 import com.idaremedia.antx.AntX;
44 import com.idaremedia.antx.AntXFixture;
45 import com.idaremedia.antx.AssertableDataType;
46 import com.idaremedia.antx.FixtureComponent;
47 import com.idaremedia.antx.apis.AntLibFriendly;
48 import com.idaremedia.antx.helpers.InnerString;
49 import com.idaremedia.antx.helpers.InputFileLoader;
50 import com.idaremedia.antx.helpers.Tk;
51 import com.idaremedia.antx.ownhelpers.LocalTk;
52 import com.idaremedia.antx.parameters.FlexSourceSupport;
53
54 /**
55  * Mapping between one or more object classes and a custom
56  * {@linkplain com.idaremedia.antx.print.DisplayStrategy display strategy}
57  * implementation. Usually defined as &lt;printer&gt;. An incomplete
58  * printer mapping is either missing a strategy implementation or has no target
59  * classnames defined (at least one must be defined). Only useful as part of a
60  * {@linkplain PrinterRegistry} or referenced from a &lt;{@linkplain PrintTask print}&gt;
61  * task.
62  * <p>
63  * <b>Examples:</b><pre>
64  * &lt;printer id="my.printer" classname="mycompany.ant.MyPrinterClass"&gt;
65  * &lt;forclass name="mycompany.ant.types.MyType"/&gt;
66  * &lt;forclass name="mycompany.ant.types.MyOtherType"/&gt;
67  * &lt;/printer&gt;
68  *
69  * &lt;printer id="my.printer" resource="builds/myprinters.properties"/&gt;
70  *
71  * &lt;printer id="my.printer" classname="mycompany.ant.MyPrinterClass"&gt;
72  * &lt;fortype name="mytype"/&gt; <i>&lt;!-- use typedef names --&gt;</i>
73  * &lt;fortype name="myothertype"/&gt;
74  * &lt;/printer&gt;
75  *
76  * &lt;printer id="my.printer" property="myprinterclass"&gt;
77  * &lt;fortype name="mytype"/&gt; <i>&lt;!-- use typedef names --&gt;</i>
78  * &lt;fortype name="myothertype"/&gt;
79  * &lt;/printer&gt;
80  * </pre>
81  *
82  * @since JWare/AntX 0.2
83  * @author ssmc, &copy;2002-2005 <a HREF="http://www.jware.info">iDare&nbsp;Media,&nbsp;Inc.</a>
84  * @version 0.5
85  * @.safety multiple (once <em>fully</em> configured)
86  * @.group api,helper
87  * @see PrinterRegistry
88  * @see PrintTask
89  **/

90
91 public class PrinterMapping extends AssertableDataType
92     implements Cloneable JavaDoc, FixtureComponent, FlexSourceSupport, AntLibFriendly
93 {
94     /**
95      * Property key that holds the mapping's display strategy class
96      * name when a <span class="src">Properties</span> resource is used
97      * to initialize a mapping. Defaults to <span class="src">{@value}</span>.
98      **/

99     public static final String JavaDoc RESOURCE_KEY= "CLASSNAME";
100
101
102
103     /**
104      * Initializes a new printer mapping instance.
105      **/

106     public PrinterMapping()
107     {
108         super(AntX.print);
109     }
110
111
112     /**
113      * Returns a clone of this printer mapping. Supports copying
114      * of printer mappings between parent and forked child projects.
115      * @since JWare/AntX 0.3
116      **/

117     public Object JavaDoc clone()
118     {
119         if (isReference()) {
120             return getPrinterRef().clone();
121         }
122         try {
123             PrinterMapping copy = (PrinterMapping)super.clone();
124             copy.m_targetClasses = (HashSet JavaDoc)m_targetClasses.clone();
125             return copy;
126         } catch(CloneNotSupportedException JavaDoc clnx) {
127             throw new Error JavaDoc(uistrs().get(AntX.CLONE_BROKEN_MSGID));
128         }
129     }
130
131
132     /**
133      * Capture our identifier for feedback since types don't always
134      * get correct location information.
135      **/

136     public void setId(String JavaDoc id)
137     {
138         m_Id= id;
139     }
140
141
142     /**
143      * Return a unique identifier for this mapping.
144      **/

145     public final String JavaDoc getId()
146     {
147         if (m_Id!=null) {
148             return m_Id;
149         }
150         if (isReference()) {
151             return getPrinterRef().getId();
152         }
153         return super.getId();
154     }
155
156
157     /**
158      * Returns <i>true</i> if this mapping if fully defined. A mapping
159      * requires at least its display strategy and one filter class to
160      * be defined before it can be used.
161      * @see #addConfiguredForClass addConfiguredForClass(...)
162      * @see #setClassName
163      **/

164     public boolean isFullyDefined()
165     {
166         if (isReference()) {
167             return getPrinterRef().isFullyDefined();
168         }
169         return m_printWorker!=null && !m_targetClasses.isEmpty();
170     }
171
172
173
174     /**
175      * Sets this mappings display strategy implementation class. Class must
176      * implement the {@linkplain com.idaremedia.antx.print.DisplayStrategy
177      * display strategy} interface.
178      * This parameter is required before this mapping can be used.
179      * @param clas the printer's implementation class (non-null)
180      * @throws BuildException if unable to create strategy instance from class
181      **/

182     public void setClassName(Class JavaDoc clas)
183     {
184         require_(clas!=null,"setClaz- nonzro clsid");
185         if (isReference()) {
186             throw tooManyAttributes();
187         }
188         try {
189             m_printWorker = (DisplayStrategy)clas.newInstance();
190         } catch(Exception JavaDoc anyX) {
191             String JavaDoc ermsg = uistrs().get("printer.bad.impl.class",
192                                         getId(), clas.getName());
193             log(ermsg,Project.MSG_ERR);
194             throw new BuildException(ermsg,anyX);
195         }
196         edited("setClassName");
197     }
198
199
200     /**
201      * Sets this mappings display strategy to the class referred to by
202      * the given property.
203      * @since JWare/AntX 0.4
204      **/

205     public void setProperty(String JavaDoc property)
206     {
207         require_(property!=null,"setProp- nonzro prop nam");
208         if (isReference()) {
209             throw tooManyAttributes();
210         }
211         String JavaDoc classname = getProject().getProperty(property);
212         if (classname!=null) {
213             try {
214                 setClassName(Class.forName(classname));
215             } catch(Exception JavaDoc anyX) {
216                 String JavaDoc ermsg = uistrs().get("printer.bad.property",
217                                             getId(), property, classname);
218                 log(ermsg,Project.MSG_ERR);
219                 throw new BuildException(ermsg,anyX);
220             }
221         } else {
222             String JavaDoc ermsg = uistrs().get("task.undef.property",property);
223             log(ermsg,Project.MSG_ERR);
224             throw new BuildException(ermsg);
225         }
226     }
227
228
229
230     /**
231      * Returns the name of this mapping's display strategy implementation.
232      * Returns <i>null</i> if no strategy implementation defined.
233      * @see #setClassName
234      **/

235     public final String JavaDoc getPrinterClassName()
236     {
237         if (isReference()) {
238             return getPrinterRef().getPrinterClassName();
239         }
240         return m_printWorker!=null ?
241             m_printWorker.getClass().getName() :
242             null;
243     }
244
245
246
247     /**
248      * Adds a new class that this mapping's printer can handle.
249      * @param clsinfo the name of the class (embedded in a &lt;forclass&gt; element)
250      * @throws BuildException if unable to load object class from name
251      **/

252     public void addConfiguredForClass(InnerString clsinfo)
253     {
254         require_(clsinfo!=null,"addForClaz- nonzro valu");
255         if (isReference()) {
256             throw tooManyAttributes();
257         }
258         String JavaDoc classname = clsinfo.getText();
259         try {
260             addTargetClass(Class.forName(classname));
261         } catch(Exception JavaDoc anyX) {
262             String JavaDoc ermsg = uistrs().get("printer.bad.item.class",
263                                         getId(), classname);
264             log(ermsg,Project.MSG_ERR);
265             throw new BuildException(ermsg,anyX);
266         }
267         edited("addForClass");
268     }
269
270
271
272     /**
273      * Adds a new typedef'ed class that this mapping's printer can
274      * handle. The type must already be registered.
275      * @since JWare/AntX 0.4
276      **/

277     public void addConfiguredForType(InnerString typedefItem)
278     {
279         require_(typedefItem!=null,"addForTyp- nonzro typdef");
280         if (isReference()) {
281             throw tooManyAttributes();
282         }
283         String JavaDoc defname = typedefItem.getText();
284         Class JavaDoc claz = (Class JavaDoc)getProject().getDataTypeDefinitions().get(defname);
285         if (claz==null) {
286             String JavaDoc ermsg = uistrs().get("printer.bad.typedef", getId(), defname);
287             log(ermsg,Project.MSG_ERR);
288             throw new BuildException(ermsg);
289         }
290         addTargetClass(claz);
291         edited("addForTypedef");
292     }
293
294
295     /**
296      * Common extraction code for a <span class="src">Properties</span>
297      * stored at a URL once the URL has been determined.
298      * @since JWare/AntX 0.4
299      * @throws BuildException if unable to load definition from URL
300      **/

301     private void setFromPropertiesURL(URL JavaDoc url, String JavaDoc from)
302     {
303         Properties JavaDoc p;
304         try {
305             p= InputFileLoader.loadProperties(url,null);
306         } catch(IOException JavaDoc iox) {
307             String JavaDoc error = uistrs().get("printer.bad.source",getId(),from);
308             log(error,Project.MSG_ERR);
309             throw new BuildException(error,iox);
310         }
311         String JavaDoc clsid = p.getProperty(RESOURCE_KEY);
312         if (clsid!=null) {
313             try {
314                 setClassName(Class.forName(clsid));
315             } catch (Exception JavaDoc anyX) {
316                 String JavaDoc error = uistrs().get("printer.bad.impl.class", getId(),clsid);
317                 log(error,Project.MSG_ERR);
318                 throw new BuildException(error,anyX);
319             }
320             p.remove(RESOURCE_KEY);
321             if (!p.isEmpty()) {
322                 Iterator JavaDoc itr= p.values().iterator();
323                 while (itr.hasNext()) {
324                     String JavaDoc classname = itr.next().toString();
325                     try {
326                         addTargetClass(Class.forName(classname));
327                     } catch(Exception JavaDoc anyX) {
328                         String JavaDoc error = uistrs().get("printer.bad.item.class",
329                                                     getId(), classname);
330                         log(error,Project.MSG_ERR);
331                         throw new BuildException(error,anyX);
332                     }
333                 }//while
334
}
335         } else {
336             String JavaDoc error = uistrs().get("printer.bad.source.class",getId(),from);
337             log(error,Project.MSG_ERR);
338             throw new BuildException(error);
339         }
340         p.clear();
341         p=null;
342     }
343
344
345     /**
346      * Completely defines this printer mapping using the contents of
347      * a single resource (<span class="src">Properties</span>) file. The
348      * display strategy class name must be stored under the
349      * "<span class="src">CLASSNAME</span>" entry. All other entries
350      * are assumed to contain target class names as values (the keys
351      * are ignored). Properly handles the output of the standard
352      * {@linkplain MappingPrinter Mapping printer}.
353      * @throws BuildException if unable to locate/load display class
354      * @throws BuildException if unable to load any target class
355      * @since JWare/AntX 0.4
356      **/

357     public void setResource(String JavaDoc rn)
358     {
359         require_(rn!=null,"setrez- nonzro nam");
360         if (isReference()) {
361             throw tooManyAttributes();
362         }
363         URL JavaDoc url = LocalTk.getSystemResource(rn, getProject());
364         if (url!=null) {
365             setFromPropertiesURL(url,rn);
366         } else {
367             String JavaDoc warning = uistrs().get("printer.bad.source",getId(),rn);
368             log(warning,Project.MSG_WARN);
369         }
370     }
371
372
373
374     /**
375      * Like {@linkplain #setResource setResource} except the Properties
376      * file is defined with a <span class="src">File</span> object.
377      * @param filepath the (Properties) file to load (non-null)
378      * @since JWare/AntX 0.4
379      **/

380     public void setFile(String JavaDoc filepath)
381     {
382         require_(filepath!=null,"setfile- nonzro filepath");
383         if (isReference()) {
384             throw tooManyAttributes();
385         }
386         try {
387             File JavaDoc file = getProject().resolveFile(filepath);
388             setFromPropertiesURL(AntXFixture.fileUtils().getFileURL(file),filepath);
389         } catch(MalformedURLException JavaDoc mux) {
390             String JavaDoc warning = uistrs().get("printer.bad.source",getId(),filepath);
391             log(warning,Project.MSG_WARN);
392         }
393     }
394
395
396
397     /**
398      * Like {@linkplain #setFile(String) setFile(path)} but with a
399      * resolved file object.
400      * @param file the (Properties) file to load (non-null)
401      * @since JWare/AntX 0.4
402      **/

403     public final void setProjectFile(File JavaDoc file)
404     {
405         require_(file!=null,"setFile- nonzro file");
406         if (isReference()) {
407             throw tooManyAttributes();
408         }
409         try {
410             setFromPropertiesURL(AntXFixture.fileUtils().getFileURL(file),file.getPath());
411         } catch(MalformedURLException JavaDoc mux) {
412             String JavaDoc warning = uistrs().get("printer.bad.source",getId(),file.getPath());
413             log(warning,Project.MSG_WARN);
414         }
415     }
416
417
418
419     /**
420      * Like {@linkplain #setResource setResource} except the Properties
421      * file is defined with a <span class="src">URL</span> string.
422      * @param urlstr the (Properties) file to load (non-null)
423      * @since JWare/AntX 0.4
424      **/

425     public void setURL(String JavaDoc urlstr)
426     {
427         require_(urlstr!=null,"setURL- nonzro URL");
428         if (isReference()) {
429             throw tooManyAttributes();
430         }
431         URL JavaDoc url = null;
432         try {
433             url = new URL JavaDoc(urlstr);
434         } catch(MalformedURLException JavaDoc mux) {/*fallthru*/}
435         if (url!=null) {
436             setFromPropertiesURL(url,urlstr);
437         } else {
438             String JavaDoc warning = uistrs().get("printer.bad.source",getId(),urlstr);
439             log(warning,Project.MSG_WARN);
440         }
441     }
442
443
444
445     /**
446      * Shortcut for adding a single or a comma-delimited list of
447      * classnames to this mapping.
448      * @param classlist comma-delimited list of class names (non-null)
449      * @see #addConfiguredForClass addConfiguredForClass(...)
450      * @throws BuildException if unable to load object class from name
451      **/

452     public final void setForClass(String JavaDoc classlist)
453     {
454         require_(classlist!=null,"setforclaz- nonzro list");
455         if (isReference()) {
456             throw tooManyAttributes();
457         }
458         List JavaDoc l = Tk.splitList(classlist);
459         if (!l.isEmpty()) {
460             InnerString helper= new InnerString();
461             for (int i=0,N=l.size();i<N;i++) {
462                 helper.setValue((String JavaDoc)l.get(i));
463                 addConfiguredForClass(helper);
464             }
465             helper=null;
466         }
467         l=null;
468     }
469
470
471     /**
472      * Shortcut for adding a single or a comma-delimited list of
473      * script-declared type names to this mapping.
474      * @param typelist comma-delimited list of typdef'ed names (non-null)
475      * @see #addConfiguredForClass addConfiguredForClass(...)
476      * @throws BuildException if unable to find typedef match
477      * @since JWare/AntX 0.4
478      **/

479     public final void setForType(String JavaDoc typelist)
480     {
481         require_(typelist!=null,"setfortype- nonzro list");
482         if (isReference()) {
483             throw tooManyAttributes();
484         }
485         List JavaDoc l = Tk.splitList(typelist);
486         if (!l.isEmpty()) {
487             InnerString helper= new InnerString();
488             for (int i=0,N=l.size();i<N;i++) {
489                 helper.setValue((String JavaDoc)l.get(i));
490                 addConfiguredForType(helper);
491             }
492             helper=null;
493         }
494         l=null;
495     }
496
497
498
499     /**
500      * Returns this mapping's display strategy implementation.
501      * @throws BuildException if no strategy defined for this mapping
502      **/

503     public DisplayStrategy getPrinter()
504     {
505         if (isReference()) {
506             return getPrinterRef().getPrinter();
507         }
508         if (m_printWorker==null) {
509             String JavaDoc ermsg = uistrs().get("printer.undefined",getId());
510             log(ermsg,Project.MSG_ERR);
511             throw new BuildException(ermsg);
512         }
513         return m_printWorker;
514     }
515
516
517
518     /**
519      * Returns <i>true</i> if this mapping applies to the given
520      * object's class. Always returns <i>false</i> if this mapping's
521      * definition is incomplete. Never matches to <i>null</i>.
522      * @param instance the object to be displayed
523      **/

524     public boolean isMatch(Object JavaDoc instance)
525     {
526         if (isReference()) {
527             return getPrinterRef().isMatch(instance);
528         }
529         if (instance!=null && isFullyDefined()) {
530             Iterator JavaDoc itr= m_targetClasses.iterator();
531             while (itr.hasNext()) {
532                 Class JavaDoc clas = (Class JavaDoc)itr.next();
533                 if (clas.isInstance(instance)) {//NB:solves CL issues (ssmc)
534
return true;
535                 }
536             }
537         }
538         return false;
539     }
540
541
542     /**
543      * Returns this mapping's reference strongly typed.
544      **/

545     protected final PrinterMapping getPrinterRef()
546     {
547         return (PrinterMapping)getCheckedRef(PrinterMapping.class,"printer");
548     }
549
550
551
552     /**
553      * Returns a live reference to this mappings underlying target
554      * classes. Used by display strategy (only). Never returns <i>null</i>.
555      * @since JWare/AntX 0.4
556      **/

557     Set JavaDoc getTargetClasses()
558     {
559         return m_targetClasses;
560     }
561
562
563
564     /**
565      * Adds handle class reference; emits warning if class already
566      * known.
567      **/

568     private void addTargetClass(Class JavaDoc claz)
569     {
570         if (!m_targetClasses.add(claz)) {
571             String JavaDoc warning = uistrs().get("printer.class.mapping.exists",
572                                           getId(), claz.getName());
573             log(warning,Project.MSG_WARN);
574         }
575     }
576
577     private String JavaDoc m_Id;
578     private HashSet JavaDoc m_targetClasses= new HashSet JavaDoc(11);
579     private DisplayStrategy m_printWorker;
580 }
581
582
583 /* end-of-PrinterMapping.java */
584
Popular Tags