Source Code Cross Referenced for Theme.java in  » Web-Framework » Millstone » org » millstone » webadapter » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » Millstone » org.millstone.webadapter 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* *************************************************************************
002:         
003:                                        Millstone(TM) 
004:                           Open Sourced User Interface Library for
005:                               Internet Development with Java
006:
007:                     Millstone is a registered trademark of IT Mill Ltd
008:                          Copyright (C) 2000-2005 IT Mill Ltd
009:                             
010:         *************************************************************************
011:
012:           This library is free software; you can redistribute it and/or
013:           modify it under the terms of the GNU Lesser General Public
014:           license version 2.1 as published by the Free Software Foundation.
015:
016:           This library is distributed in the hope that it will be useful,
017:           but WITHOUT ANY WARRANTY; without even the implied warranty of
018:           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019:           Lesser General Public License for more details.
020:
021:           You should have received a copy of the GNU Lesser General Public
022:           License along with this library; if not, write to the Free Software
023:           Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024:
025:         *************************************************************************
026:           
027:           For more information, contact:
028:           
029:           IT Mill Ltd                           phone: +358 2 4802 7180
030:           Ruukinkatu 2-4                        fax:  +358 2 4802 7181
031:           20540, Turku                          email: info@itmill.com
032:           Finland                               company www: www.itmill.com
033:           
034:           Primary source for MillStone information and releases: www.millstone.org
035:
036:         ********************************************************************** */
037:
038:        package org.millstone.webadapter;
039:
040:        import java.io.FileInputStream;
041:        import java.io.FileNotFoundException;
042:        import java.io.IOException;
043:        import java.io.InputStream;
044:        import java.util.Collection;
045:        import java.util.Iterator;
046:        import java.util.LinkedList;
047:        import java.util.List;
048:        import java.util.Stack;
049:        import javax.xml.parsers.ParserConfigurationException;
050:        import javax.xml.parsers.SAXParserFactory;
051:        import org.xml.sax.helpers.DefaultHandler;
052:        import org.xml.sax.SAXException;
053:        import org.xml.sax.InputSource;
054:        import org.xml.sax.XMLReader;
055:        import org.xml.sax.Attributes;
056:
057:        /** This class provides an interface to the meta-information
058:         *  regarding a particular webadapter theme. This entails for
059:         *  instanace the inheritance tree of the various xsl-template files,
060:         *  the different requirments that the theme imposes on the client browser,
061:         *  etc.
062:         *  <p>
063:         *  The WebAdapter uses themes to convert the UIDL description into
064:         *  client representation, typically HTML or XHTML.
065:         *  A theme consists of set of XSL template files which are used to 
066:         *  perform XSL transform.
067:         *  </p>
068:         *  <p>
069:         *  XSL files are divided into sets, which can have requirements.
070:         *  A file set is included in transformation only if the given requirements
071:         *  are met. Following requirements are supported:
072:         *  <ul>
073:         *      <li>User-Agent HTTP header substring matching</li>
074:         *      <li>Markup language version</li>
075:         *      <li>JavaScript version</li>
076:         *  </ul>
077:         *  Additionally following boolean operators may be applied to above
078:         *  requirements:
079:         *  <ul>
080:         *      <li>NOT</li>
081:         *      <li>AND</li>
082:         *      <li>OR</li>
083:         *  </ul>
084:         *  The requirements are introduced in XML description file. See example below.
085:         *  </p>
086:         *  <p>
087:         *  The theme description is XML data, and it can be loaded from file or stream. 
088:         *  The default filename is specified by <code>Theme.DESCRIPTIONFILE</code>.
089:         *  Example of theme description file:
090:         *  <pre>
091:         *  &lt;?xml version="1.0" encoding="UTF-8"?&gt;
092:         *
093:         *  &lt;theme name="normal"&gt;
094:         * 
095:         *  &lt;extends theme="simple"/&gt;
096:         *     
097:         *  &lt;description&gt;The normal theme for all browsers&lt;/description&gt;
098:         *  &lt;author name="IT Mill Ltd" email="millstone@itmill.com" /&gt;
099:         *
100:         *      &lt;fileset&gt;
101:         *          &lt;require&gt;
102:         *              &lt;supports javascript="JavaScript 1.0"/&gt;
103:         *          &lt;/require&gt;
104:         *
105:         *          &lt;file name="common/error.xsl" /&gt; 
106:         *          &lt;file name="components/button.xsl" /&gt; 
107:         *          &lt;file name="components/select.xsl" /&gt;
108:         *          &lt;file name="components/textfield.xsl" /&gt;
109:         *          &lt;file name="components/table.xsl" /&gt;
110:         *      &lt;/fileset&gt;
111:         *  &lt;/theme&gt;
112:         *  </pre>
113:         *  </p>
114:         * @author IT Mill Ltd.
115:         * @version 3.1.1
116:         * @since 3.0
117:         */
118:        public class Theme extends DefaultHandler {
119:
120:            /** Default description file name. */
121:            public static final String DESCRIPTIONFILE = "description.xml";
122:
123:            private static final String TAG_THEME = "theme";
124:            private static final String TAG_EXTENDS = "extends";
125:            private static final String TAG_DESCRIPTION = "description";
126:
127:            private static final String TAG_FILE = "file";
128:            private static final String TAG_FILESET = "fileset";
129:            private static final String TAG_REQUIRE = "require";
130:            private static final String TAG_SUPPORTS = "supports";
131:            private static final String TAG_AUTHOR = "author";
132:
133:            private static final String TAG_AND = "and";
134:            private static final String TAG_OR = "or";
135:            private static final String TAG_NOT = "not";
136:
137:            private static final String ATTR_NAME = "name";
138:            private static final String ATTR_THEME = "theme";
139:            private static final String ATTR_EMAIL = "email";
140:
141:            private static final String ATTR_JAVASCRIPT = "javascript";
142:            private static final String ATTR_AGENT = "agent";
143:            private static final String ATTR_MARKUP = "markup";
144:
145:            private static final String UNNAMED_FILESET = "unnamed";
146:
147:            /** Name of the theme. */
148:            private String name;
149:
150:            /** Description file. */
151:            private java.io.File file;
152:
153:            /** Version of the theme. */
154:            private String version;
155:
156:            /** Theme description. */
157:            private String description;
158:
159:            /** Author of the theme. */
160:            private Author author;
161:
162:            /** List of parent themes */
163:            private List parentThemes = new LinkedList();
164:
165:            /** Fileset of included XSL files. */
166:            private Fileset files = null;
167:
168:            /** Stack of fileset used while parsing XML. */
169:            private Stack openFilesets = new Stack();
170:
171:            /** Stack of string buffers used while parsing XML. */
172:            private Stack openStrings = new Stack();
173:
174:            /** Is a NOT requirement element open. */
175:            private boolean isNOTRequirementOpen = false;
176:
177:            /** Currently open requirements while parsing. */
178:            private Stack openRequirements = new Stack();
179:
180:            /** Creates a new instance using XML description file. 
181:             *  Instantiate new theme, by loading the description from given File.
182:             *  @param descriptionFile Description file
183:             *  @throws FileNotFoundException Thrown if the given file is not found.
184:             */
185:            public Theme(java.io.File descriptionFile)
186:                    throws FileNotFoundException {
187:                this .file = descriptionFile;
188:                parse(new InputSource(new FileInputStream(descriptionFile)));
189:            }
190:
191:            /** Creates a new instance using XML description stream. 
192:             *  Instantiate new theme, by loading the description from given InputSource.
193:             *  @param descriptionStream XML input to parse
194:             */
195:            public Theme(InputStream descriptionStream) {
196:                try {
197:                    parse(new InputSource(descriptionStream));
198:                } finally {
199:                    try {
200:                        descriptionStream.close();
201:                    } catch (IOException ignored) {
202:                    }
203:                }
204:            }
205:
206:            /** Parse XML data.
207:             *  @param descriptionSource XML input source to parse
208:             */
209:            private synchronized void parse(InputSource descriptionSource) {
210:
211:                // Clean-up parse time data
212:                this .openStrings.clear();
213:                this .openFilesets.clear();
214:                this .openRequirements.clear();
215:                this .files = null;
216:
217:                // Parse the Document
218:                try {
219:                    XMLReader xr = SAXParserFactory.newInstance()
220:                            .newSAXParser().getXMLReader();
221:
222:                    xr.setContentHandler(this );
223:                    xr.setErrorHandler(this );
224:
225:                    xr.parse(descriptionSource);
226:
227:                    return;
228:                } catch (ParserConfigurationException e) {
229:                    e.printStackTrace();
230:                } catch (SAXException e) {
231:                    e.getException().printStackTrace();
232:                } catch (IOException e) {
233:                    e.printStackTrace();
234:                } finally {
235:                }
236:
237:            }
238:
239:            /** Parse start tag in XML stream.
240:             * 
241:             * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
242:             */
243:            public void startElement(String uri, String local, String qName,
244:                    Attributes atts) {
245:
246:                if (TAG_THEME.equals(qName)) {
247:                    this .name = atts.getValue(ATTR_NAME);
248:                } else if (TAG_DESCRIPTION.equals(qName)) {
249:                    this .description = "(none)";
250:                    this .openStrings.push(new StringBuffer());
251:                } else if (TAG_EXTENDS.equals(qName)) {
252:                    String themeName = atts.getValue(ATTR_THEME);
253:                    if (this .name.equals(themeName))
254:                        throw new IllegalArgumentException("Theme " + this .name
255:                                + " extends itself.");
256:                    this .parentThemes.add(themeName);
257:                } else if (TAG_FILE.equals(qName)) {
258:                    File f = new File(atts.getValue(ATTR_NAME));
259:                    if (this .openFilesets.isEmpty()) {
260:                        throw new IllegalStateException("Element '" + TAG_FILE
261:                                + "' must be within '" + TAG_FILESET
262:                                + "' element.");
263:                    }
264:                    Fileset fs = (Fileset) this .openFilesets.peek();
265:                    fs.addFile(f);
266:                } else if (TAG_FILESET.equals(qName)) {
267:                    Fileset fs;
268:                    if (atts.getValue(ATTR_NAME) != null) {
269:                        fs = new Fileset(atts.getValue(ATTR_NAME));
270:                    } else {
271:                        fs = new Fileset(atts.getValue(UNNAMED_FILESET));
272:                    }
273:
274:                    // Use the first fileset as root fileset
275:                    if (this .files == null) {
276:                        this .files = fs;
277:                    }
278:
279:                    // Add inner filesets to parent
280:                    if (!this .openFilesets.isEmpty()) {
281:                        ((Fileset) this .openFilesets.peek()).addFile(fs);
282:                    }
283:
284:                    this .openFilesets.push(fs);
285:                } else if (TAG_AUTHOR.equals(qName)) {
286:                    this .author = new Author(atts.getValue(ATTR_NAME), atts
287:                            .getValue(ATTR_EMAIL));
288:                }
289:
290:                // Requirements
291:                else if (TAG_REQUIRE.equals(qName)) {
292:                    if (this .openFilesets.isEmpty()) {
293:                        throw new IllegalStateException("Element '"
294:                                + TAG_REQUIRE + "' must be within '"
295:                                + TAG_FILESET + "' element.");
296:                    }
297:                    Fileset fs = (Fileset) this .openFilesets.peek();
298:                    this .openRequirements.push(fs.getRequirements());
299:                } else if (TAG_SUPPORTS.equals(qName)) {
300:                    if (this .openFilesets.isEmpty()) {
301:                        throw new IllegalStateException("Element '"
302:                                + TAG_REQUIRE + "' must be within '"
303:                                + TAG_FILESET + "' element.");
304:                    }
305:                    if (this .openRequirements.isEmpty()) {
306:                        throw new IllegalStateException("Element '"
307:                                + TAG_SUPPORTS + "' must be within '"
308:                                + TAG_REQUIRE + "' element.");
309:                    }
310:                    this .addRequirements(atts,
311:                            (RequirementCollection) this .openRequirements
312:                                    .peek(), this .isNOTRequirementOpen);
313:                } else if (TAG_NOT.equals(qName)) {
314:                    this .isNOTRequirementOpen = true;
315:                } else if (TAG_AND.equals(qName)) {
316:                    this .openRequirements.push(new AndRequirement());
317:                } else if (TAG_OR.equals(qName)) {
318:                    this .openRequirements.push(new OrRequirement());
319:                }
320:            }
321:
322:            /** Parse end tag in XML stream.
323:             * @see org.xml.sax.ContentHandler#endElement(String, String, String)
324:             */
325:            public void endElement(String namespaceURI, String localName,
326:                    String qName) throws SAXException {
327:
328:                if (TAG_FILESET.equals(qName)) {
329:                    this .openFilesets.pop();
330:                } else if (TAG_DESCRIPTION.equals(qName)) {
331:                    this .description = ((StringBuffer) this .openStrings.pop())
332:                            .toString();
333:                } else if (TAG_REQUIRE.equals(qName)) {
334:                    this .openRequirements.pop();
335:
336:                } else if (TAG_NOT.equals(qName)) {
337:                    this .isNOTRequirementOpen = false;
338:                }
339:            }
340:
341:            /** Parse character data in XML stream.
342:             * @see org.xml.sax.ContentHandler#characters(char[], int, int)
343:             */
344:            public void characters(char[] data, int start, int length) {
345:
346:                // if stack is not ready, data is not content of recognized element
347:                if (!this .openStrings.isEmpty()) {
348:                    ((StringBuffer) this .openStrings.peek()).append(data,
349:                            start, length);
350:                } else {
351:                    // read data which is not part of recognized element
352:                }
353:            }
354:
355:            /** Add all requirements specified in attributes to fileset. 
356:             *  @param atts Attribute set
357:             *  @param requirements Collection where to add requirement rules.
358:             *  @param applyNot Should the meaning of these requirement be negated.
359:             */
360:            private void addRequirements(Attributes atts,
361:                    RequirementCollection requirements, boolean applyNot) {
362:
363:                // Create temporary collection for requirements
364:                Collection tmpReqs = new LinkedList();
365:                Requirement req = null;
366:
367:                for (int i = 0; i < atts.getLength(); i++) {
368:                    req = null;
369:                    if (ATTR_JAVASCRIPT.equals(atts.getQName(i))) {
370:                        req = new JavaScriptRequirement(WebBrowser
371:                                .parseJavaScriptVersion(atts.getValue(i)));
372:                    } else if (ATTR_AGENT.equals(atts.getQName(i))) {
373:                        req = new AgentRequirement(atts.getValue(i));
374:                    } else if (ATTR_MARKUP.equals(atts.getQName(i))) {
375:                        req = new MarkupLanguageRequirement(WebBrowser
376:                                .parseHTMLVersion(atts.getValue(i)));
377:                    }
378:                    // Add to temporary requirement collection and clear reference
379:                    if (req != null)
380:                        tmpReqs.add(req);
381:                }
382:
383:                // Create implicit AND requirement if more than one 
384:                // Rrequirements were specified in attributes
385:                if (tmpReqs.size() > 1) {
386:                    req = new AndRequirement(tmpReqs);
387:                }
388:
389:                // Apply NOT rule if requested
390:                if (applyNot) {
391:                    req = new NotRequirement(req);
392:                }
393:
394:                // Add to requirements
395:                requirements.addRequirement(req);
396:            }
397:
398:            /** Get list of all files in this theme.
399:             * @return List of filenames belonging to this theme.
400:             */
401:            public List getFileNames() {
402:                if (files == null)
403:                    return new LinkedList();
404:                return files.getFileNames();
405:            }
406:
407:            /** Get list of file names matching WebBrowserType.
408:             * @return list of filenames in this theme supporting the given terminal.
409:             */
410:            public List getFileNames(WebBrowser terminal) {
411:                if (files == null)
412:                    return new LinkedList();
413:                return this .files.getFileNames(terminal);
414:            }
415:
416:            /** String representation of Theme object.
417:             *  Used for debugging purposes only.
418:             *  @see java.lang.Object#toString()
419:             */
420:            public String toString() {
421:                return this .name + " author=[" + this .author + "]"
422:                        + " inherits=" + parentThemes + "]" + " files={"
423:                        + (files != null ? files.toString() : "null") + "}";
424:            }
425:
426:            /** Author information class.
427:             *  This class represents an single author of a theme package.
428:             *  Authors have name and contact email address properties.
429:             * @author IT Mill Ltd.
430:             * @version 3.1.1
431:             * @since 3.0   
432:             */
433:            public class Author {
434:
435:                private String name;
436:                private String email;
437:
438:                public Author(String name, String email) {
439:                    this .name = name;
440:                    this .email = email;
441:                }
442:
443:                /** Get the name of the author.
444:                 * @return Name of the author.
445:                 */
446:                public String getName() {
447:                    return this .name;
448:                }
449:
450:                /** Get the email address of the author.
451:                 * @return Email address of the author.
452:                 */
453:                public String getEmail() {
454:                    return this .email;
455:                }
456:
457:                /**
458:                 * @see java.lang.Object#toString()
459:                 */
460:                public String toString() {
461:                    return name + "(" + email + ")";
462:                }
463:            }
464:
465:            /** Generic requirement.
466:             *  Interface implemented by reuirements introducing
467:             *  method for checking compability with given terminal.
468:             * @author IT Mill Ltd.
469:             * @version 3.1.1
470:             * @since 3.0
471:             */
472:            public interface Requirement {
473:
474:                /** Check that this requirement is met by given type of browser.
475:                 * @param terminal type of the web browser.
476:                 * @return True if terminal is compatible with this rule. False otherwise.
477:                 */
478:                public boolean isMet(WebBrowser terminal);
479:
480:            }
481:
482:            /** Generic requirement collection interface.
483:             *  Requirement collection introducing methods for
484:             *  combining requirements into single requirement.
485:             * @author IT Mill Ltd.
486:             * @version 3.1.1
487:             * @since 3.0
488:             */
489:            public interface RequirementCollection extends Requirement {
490:
491:                /** Add new requirement to this collection. 
492:                 * @param requirement Requirement to be added.
493:                 */
494:                public void addRequirement(Requirement requirement);
495:
496:                /** Remove a requirement from this collection. 
497:                 * @param requirement Requirement to be removed.
498:                 */
499:                public void removeRequirement(Requirement requirement);
500:            }
501:
502:            /** Logical NOT requirement.
503:             *  Requirement implementing logical NOT operation.
504:             *  Wraps an another requirement and negates the meaning of it.
505:             * @author IT Mill Ltd.
506:             * @version 3.1.1
507:             * @since 3.0
508:             */
509:            public class NotRequirement implements  Requirement {
510:                private Requirement requirement;
511:
512:                /** Create new NOT requirement based on another requirement.
513:                 * @param requirement The requirement to ne negated.
514:                 */
515:                public NotRequirement(Requirement requirement) {
516:                    this .requirement = requirement;
517:                }
518:
519:                /** Check that this requirement is met by given type of browser.
520:                 * @param terminal type of the web browser.
521:                 * @return True if terminal is compatible with this rule. False otherwise.
522:                 */
523:                public boolean isMet(WebBrowser terminal) {
524:                    return !this .requirement.isMet(terminal);
525:                }
526:
527:                /**
528:                 * @see java.lang.Object#toString()
529:                 */
530:                public String toString() {
531:                    return "not(" + requirement + ")";
532:                }
533:
534:            }
535:
536:            /** Logical AND requirement. 
537:             *  Implements a collection of requirements combining the 
538:             *  included requirements using logical AND operation.
539:             * @author IT Mill Ltd.
540:             * @version 3.1.1
541:             * @since 3.0
542:             */
543:            public class AndRequirement implements  RequirementCollection {
544:
545:                private Collection requirements = new LinkedList();
546:
547:                public AndRequirement() {
548:                }
549:
550:                public AndRequirement(Collection requirements) {
551:                    this .requirements.addAll(requirements);
552:                }
553:
554:                public AndRequirement(Requirement req1, Requirement req2) {
555:                    this .addRequirement(req1);
556:                    this .addRequirement(req2);
557:                }
558:
559:                public void addRequirement(Requirement requirement) {
560:                    this .requirements.add(requirement);
561:                }
562:
563:                public void removeRequirement(Requirement requirement) {
564:                    this .requirements.remove(requirement);
565:                }
566:
567:                /** Checks that all os the requirements in this collection are met. 
568:                 * @see Theme.Requirement#isMet(WebBrowser)
569:                 */
570:                public boolean isMet(WebBrowser terminal) {
571:                    for (Iterator i = this .requirements.iterator(); i.hasNext();) {
572:                        if (!((Requirement) i.next()).isMet(terminal))
573:                            return false;
574:                    }
575:                    return true;
576:                }
577:
578:                public String toString() {
579:                    String str = "";
580:                    for (Iterator i = this .requirements.iterator(); i.hasNext();) {
581:                        if (!"".equals(str))
582:                            str += " AND ";
583:                        str += "(" + ((Requirement) i.next()).toString() + ")";
584:                    }
585:                    return str;
586:                }
587:
588:            }
589:
590:            /** Logical OR requirement. 
591:             *  Implements a collection of requirements combining the 
592:             *  included requirements using logical AND operation.
593:             * @author IT Mill Ltd.
594:             * @version 3.1.1
595:             * @since 3.0
596:             */
597:            public class OrRequirement implements  RequirementCollection {
598:
599:                private Collection requirements = new LinkedList();
600:
601:                public OrRequirement() {
602:                }
603:
604:                public OrRequirement(Collection requirements) {
605:                    this .requirements.addAll(requirements);
606:                }
607:
608:                public OrRequirement(Requirement req1, Requirement req2) {
609:                    this .addRequirement(req1);
610:                    this .addRequirement(req2);
611:                }
612:
613:                public void addRequirement(Requirement requirement) {
614:                    this .requirements.add(requirement);
615:                }
616:
617:                public void removeRequirement(Requirement requirement) {
618:                    this .requirements.remove(requirement);
619:                }
620:
621:                /** Checks that some of the requirements in this collection is met. 
622:                 * @see Theme.Requirement#isMet(WebBrowser)
623:                 */
624:                public boolean isMet(WebBrowser terminal) {
625:                    for (Iterator i = this .requirements.iterator(); i.hasNext();) {
626:                        if (!((Requirement) i.next()).isMet(terminal))
627:                            return false;
628:                    }
629:                    return true;
630:                }
631:
632:                public String toString() {
633:                    String str = "";
634:                    for (Iterator i = this .requirements.iterator(); i.hasNext();) {
635:                        if (!"".equals(str))
636:                            str += " OR ";
637:                        str += "(" + ((Requirement) i.next()).toString() + ")";
638:                    }
639:                    return str;
640:                }
641:            }
642:
643:            /** HTTP user agent requirement 
644:             *  This requirements is used to ensure that the User-Agent string
645:             *  provided in HTTP request headers contains given substring.
646:             * @author IT Mill Ltd.
647:             * @version 3.1.1
648:             * @since 3.0
649:             */
650:            public class AgentRequirement implements  Requirement {
651:
652:                private String agentSubstring;
653:
654:                public AgentRequirement(String agentSubString) {
655:                    this .agentSubstring = agentSubString;
656:                }
657:
658:                public boolean isMet(WebBrowser terminal) {
659:                    if (terminal.getBrowserApplication().indexOf(
660:                            this .agentSubstring) > 0)
661:                        return true;
662:                    Log.info("Requirement: '" + this .agentSubstring
663:                            + "' is not met by "
664:                            + terminal.getBrowserApplication());
665:                    return false;
666:                }
667:
668:                /**
669:                 * @see java.lang.Object#toString()
670:                 */
671:                public String toString() {
672:                    return this .agentSubstring;
673:                }
674:            }
675:
676:            /** Javascript version requirement 
677:             *  This requirement is used to ensure a certain level of 
678:             *  JavaScript version support.
679:             * @author IT Mill Ltd.
680:             * @version 3.1.1
681:             * @since 3.0
682:             */
683:            public class JavaScriptRequirement implements  Requirement {
684:
685:                private WebBrowser.JavaScriptVersion requiredVersion;
686:
687:                public JavaScriptRequirement(
688:                        WebBrowser.JavaScriptVersion requiredVersion) {
689:                    this .requiredVersion = requiredVersion;
690:                }
691:
692:                public boolean isMet(WebBrowser terminal) {
693:                    if (terminal.getJavaScriptVersion().supports(
694:                            this .requiredVersion))
695:                        return true;
696:                    Log.info("Requirement: " + this .requiredVersion
697:                            + " is not met by "
698:                            + terminal.getJavaScriptVersion());
699:                    return false;
700:                }
701:
702:                /**
703:                 * @see java.lang.Object#toString()
704:                 */
705:                public String toString() {
706:                    return this .requiredVersion.toString();
707:                }
708:            }
709:
710:            /** Markup language version requirement 
711:             *  This requirement is used to ensure a certain level of 
712:             *  Markup language version support.
713:             * @author IT Mill Ltd.
714:             * @version 3.1.1
715:             * @since 3.0
716:             */
717:            public class MarkupLanguageRequirement implements  Requirement {
718:
719:                private WebBrowser.MarkupVersion requiredVersion;
720:
721:                public MarkupLanguageRequirement(
722:                        WebBrowser.MarkupVersion requiredVersion) {
723:                    this .requiredVersion = requiredVersion;
724:                }
725:
726:                public boolean isMet(WebBrowser terminal) {
727:                    if (terminal.getMarkupVersion().supports(
728:                            this .requiredVersion))
729:                        return true;
730:                    Log.info("Requirement: " + this .requiredVersion
731:                            + " is not met by " + terminal.getMarkupVersion());
732:                    return false;
733:
734:                }
735:
736:                /**
737:                 * @see java.lang.Object#toString()
738:                 */
739:                public String toString() {
740:                    return this .requiredVersion.toString();
741:                }
742:
743:            }
744:
745:            /** Theme XSL file description 
746:             *  Description of a single XSL file included a theme.
747:             * @author IT Mill Ltd.
748:             * @version 3.1.1
749:             * @since 3.0
750:             */
751:            public class File {
752:
753:                private String name;
754:
755:                /** Create new file.
756:                 * @param name Name of the file.
757:                 */
758:                public File(String name) {
759:                    this .name = name;
760:                }
761:
762:                /** Get name of the file.
763:                 *  The file name is relative and unique within a theme.
764:                 *  @return Name of the file.
765:                 */
766:                public String getName() {
767:                    return this .name;
768:                }
769:
770:                /** Does this file support the given terminal.
771:                 *  Single file requirements are not supported and
772:                 *  therefore this always returns true.
773:                 * @see Theme.Fileset
774:                 * @return Always returns true.
775:                 */
776:                public boolean supports(WebBrowser terminal) {
777:                    return true;
778:                }
779:
780:                /**
781:                 * @see java.lang.Object#toString()
782:                 */
783:                public String toString() {
784:                    return this .getName();
785:                }
786:
787:            }
788:
789:            /** A recursive set of files sharing the same requirements.
790:             * @author IT Mill Ltd.
791:             * @version 3.1.1
792:             * @since 3.0    
793:             */
794:            public class Fileset extends File {
795:
796:                private RequirementCollection requirements = new AndRequirement();
797:
798:                private Collection files = new LinkedList();
799:
800:                /** Create new empty fileset. 
801:                 * @param name Name of the fileset.
802:                 */
803:                public Fileset(String name) {
804:                    super (name);
805:                }
806:
807:                /** Create new fileset. 
808:                 * @param name Name of the fileset.
809:                 * @param files Collection of files to include in the set.
810:                 */
811:                public Fileset(String name, Collection files) {
812:                    super (name);
813:                }
814:
815:                /**Add a file into fileset. */
816:                private void addFile(File file) {
817:                    this .files.add(file);
818:                }
819:
820:                /** Remove a file from fileset. */
821:                private void removeFile(File file) {
822:                    this .files.add(file);
823:                }
824:
825:                /** Get requirements in this fileset. */
826:                private RequirementCollection getRequirements() {
827:                    return this .requirements;
828:                }
829:
830:                /** Get list of all files in this theme.
831:                 * @return list of filenames.
832:                 */
833:                public List getFileNames() {
834:
835:                    List list = new LinkedList();
836:
837:                    for (Iterator i = this .files.iterator(); i.hasNext();) {
838:                        File f = (File) i.next();
839:
840:                        // Recursively add included filesets
841:                        if (f instanceof  Fileset) {
842:                            list.addAll(((Fileset) f).getFileNames());
843:                        } else {
844:                            list.add(f.getName());
845:                        }
846:                    }
847:                    return list;
848:
849:                }
850:
851:                /** Get list of file names matching WebBrowserType.
852:                 * @return list of filenames supporting the given terminal.
853:                 */
854:                public List getFileNames(WebBrowser terminal) {
855:
856:                    List list = new LinkedList();
857:
858:                    if (!this .supports(terminal))
859:                        return list;
860:
861:                    for (Iterator i = this .files.iterator(); i.hasNext();) {
862:                        File f = (File) i.next();
863:
864:                        // Recursively add included filesets if they are
865:                        // supported
866:                        if (f instanceof  Fileset) {
867:                            list.addAll(((Fileset) f).getFileNames(terminal));
868:
869:                        } else {
870:                            list.add(f.getName());
871:                        }
872:                    }
873:                    return list;
874:                }
875:
876:                /** Does this file support the given terminal.
877:                 * @return True if fileset supports the given browser. False otherwise.
878:                 */
879:                public boolean supports(WebBrowser terminal) {
880:                    if (requirements.isMet(terminal))
881:                        return true;
882:                    Log.info("Skipped fileset " + Theme.this .getName() + "/"
883:                            + this .getName()
884:                            + " because all requirements were not met.");
885:                    return false;
886:                }
887:
888:                /**
889:                 * @see java.lang.Object#toString()
890:                 */
891:                public String toString() {
892:                    return "name=[" + this .getName() + "] requires=["
893:                            + this .requirements + "] files=[" + files + "]";
894:                }
895:            }
896:
897:            /** Returns the author of this theme.
898:             * @return Author of the theme.
899:             */
900:            public Author getAuthor() {
901:                return author;
902:            }
903:
904:            /** Returns the name of this theme.
905:             * @return Name of the theme.
906:             */
907:            public String getName() {
908:                return name;
909:            }
910:
911:            /** Returns the list of parent themes of this theme.
912:             * Returns list of all inherited themes in the inheritance order.
913:             * @return List of parent theme instances.
914:             */
915:            public List getParentThemes() {
916:                return parentThemes;
917:            }
918:
919:            /** Returns the version of this theme.
920:             * @return Version string
921:             */
922:            public String getVersion() {
923:                return version;
924:            }
925:
926:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.