Source Code Cross Referenced for Site.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » engine » 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 » rife 1.6.1 » com.uwyn.rife.engine 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003:         * Distributed under the terms of either:
004:         * - the common development and distribution license (CDDL), v1.0; or
005:         * - the GNU Lesser General Public License, v2.1 or later
006:         * $Id: Site.java 3806 2007-06-24 21:12:50Z gbevin $
007:         */
008:        package com.uwyn.rife.engine;
009:
010:        import java.util.*;
011:
012:        import com.uwyn.rife.config.RifeConfig;
013:        import com.uwyn.rife.continuations.ContinuationManager;
014:        import com.uwyn.rife.engine.exceptions.DuplicateElementIdException;
015:        import com.uwyn.rife.engine.exceptions.ElementIdNotFoundException;
016:        import com.uwyn.rife.engine.exceptions.EngineException;
017:        import com.uwyn.rife.engine.exceptions.FallbackUrlExistsException;
018:        import com.uwyn.rife.engine.exceptions.UrlExistsException;
019:        import com.uwyn.rife.rep.Participant;
020:        import com.uwyn.rife.rep.Rep;
021:        import com.uwyn.rife.resources.ResourceFinder;
022:        import com.uwyn.rife.resources.exceptions.ResourceFinderErrorException;
023:        import com.uwyn.rife.tools.TerracottaUtils;
024:        import java.lang.reflect.Method;
025:        import java.util.regex.Matcher;
026:
027:        /**
028:         * A <code>Site</code> contains all the elements that will be used to handle
029:         * web requests
030:         *
031:         * @author Geert Bevin (gbevin[remove] at uwyn dot com)
032:         * @version $Revision: 3806 $
033:         * @since 1.0
034:         */
035:        public class Site {
036:            public final static String DEFAULT_PARTICIPANT_NAME = "ParticipantSite";
037:
038:            private String mDeclarationName = null;
039:            private SiteData mData = new SiteData();
040:            private Set<SiteListener> mListeners = null;
041:            private volatile Long mLastModificationCheck = 0L;
042:
043:            protected Site() {
044:            }
045:
046:            void setDeclarationName(String declarationName) {
047:                assert declarationName != null;
048:
049:                mDeclarationName = declarationName;
050:            }
051:
052:            void setResourceFinder(ResourceFinder resourceFinder) {
053:                assert resourceFinder != null;
054:
055:                mData.mResourceFinder = resourceFinder;
056:            }
057:
058:            void addResourceModificationTime(UrlResource location,
059:                    long modificationTime) {
060:                if (RifeConfig.Engine.getSiteAutoReload()) {
061:                    if (null == mData.mResourceModificationTimes) {
062:                        mData.mResourceModificationTimes = new HashMap<UrlResource, Long>();
063:                    }
064:
065:                    mData.mResourceModificationTimes.put(location, new Long(
066:                            modificationTime));
067:                }
068:            }
069:
070:            /**
071:             * Retrieves a map of all the resources that were used to construct the site
072:             * and their last modification time.
073:             *
074:             * @return the map of resources with their modification times; or
075:             * <p><code>null</code> if the site was totally built manually or if the
076:             * <code>SITE_AUTO_RELOAD</code> configuration parameter was not set to
077:             * <code>true</code> at the time of construction.
078:             * @since 1.0
079:             */
080:            public Map<UrlResource, Long> getResourceModificationTimes() {
081:                if (null == mData.mResourceModificationTimes) {
082:                    return Collections.EMPTY_MAP;
083:                }
084:                return mData.mResourceModificationTimes;
085:            }
086:
087:            /**
088:             * Resets the last modification check so that the next request will always
089:             * check for modifications.
090:             * 
091:             * @since 1.5.1
092:             */
093:            public void resetLastModificationCheck() {
094:                synchronized (mLastModificationCheck) {
095:                    mLastModificationCheck = 0L;
096:                }
097:            }
098:
099:            private boolean isModified() throws EngineException {
100:                if (null != mData.mResourceModificationTimes) {
101:                    long current_modification_time = 0;
102:
103:                    for (Map.Entry<UrlResource, Long> resource_entry : mData.mResourceModificationTimes
104:                            .entrySet()) {
105:                        try {
106:                            current_modification_time = mData.mResourceFinder
107:                                    .getModificationTime(resource_entry
108:                                            .getKey().getUrl());
109:                        } catch (ResourceFinderErrorException e) {
110:                            // resource couldn't be found, consider it as not modified
111:                            return false;
112:                        }
113:
114:                        if (resource_entry.getValue().longValue() != current_modification_time) {
115:                            if (getClass().getClassLoader() instanceof  EngineClassLoader
116:                                    && resource_entry.getKey().getUrl()
117:                                            .getFile().endsWith(".class")) {
118:                                ((EngineClassLoader) getClass()
119:                                        .getClassLoader())
120:                                        .markClassAsModified(resource_entry
121:                                                .getKey().getSourceName());
122:                            }
123:                            return true;
124:                        }
125:                    }
126:                }
127:
128:                return false;
129:            }
130:
131:            private void checkModification() throws EngineException {
132:                if (null != mData.mResourceModificationTimes) {
133:                    synchronized (mLastModificationCheck) {
134:                        if (System.currentTimeMillis() - mLastModificationCheck <= RifeConfig.Global
135:                                .getAutoReloadDelay()) {
136:                            return;
137:                        }
138:                        mLastModificationCheck = System.currentTimeMillis();
139:                    }
140:
141:                    synchronized (this ) {
142:                        if (isModified()) {
143:                            SiteBuilder builder = new SiteBuilder(
144:                                    mDeclarationName, mData.mResourceFinder);
145:                            Site new_site = null;
146:
147:                            new_site = builder.getSite();
148:
149:                            // only replace the site data when the root site builder was not manually processed
150:                            if (new_site != null
151:                                    && !SiteProcessorFactory.MANUAL_IDENTIFIER
152:                                            .equals(builder
153:                                                    .getSiteProcessorIdentifier())) {
154:                                populateFromOther(new_site);
155:                            }
156:
157:                            fireModified();
158:                        }
159:                    }
160:                }
161:            }
162:
163:            /**
164:             * Clears the cached data
165:             * 
166:             * @since 1.5.1
167:             */
168:            public synchronized void clearCaches() {
169:                this .mData.clearCaches();
170:            }
171:
172:            /**
173:             * Populates this site instance from another site instance.
174:             * <p>This method is typically used during the implementation of a {@link SiteListener#modified}
175:             * method. Doing this, will ensure that the active request as well as
176:             * subsequent requests will be executed against the data of the other site
177:             * instance.
178:             *
179:             * @param otherSite the other site that will be used to replace this site's
180:             * data with
181:             * @since 1.5
182:             */
183:            public synchronized void populateFromOther(Site otherSite) {
184:                this .mData = otherSite.mData;
185:                this .mData.clearCaches();
186:
187:                for (ElementInfo element_info : otherSite.getElementInfos()) {
188:                    element_info.setSite(this );
189:                }
190:            }
191:
192:            /**
193:             * Indicates whether the default repository has a participant named
194:             * "<code>ParticipantSite</code>".
195:             *
196:             * @return <code>true</code> if that participant was present; or
197:             * <p><code>false</code> otherwise
198:             * @see Rep#getDefaultRepository
199:             * @see Participant
200:             * @since 1.0
201:             */
202:            public static boolean hasRepInstance() {
203:                return Rep.hasParticipant(DEFAULT_PARTICIPANT_NAME);
204:            }
205:
206:            /**
207:             * Retrieves the participant named "<code>ParticipantSite</code>" from the
208:             * default repository.
209:             *
210:             * @return the participant; or
211:             * <p><code>null</code> if no such participant was present
212:             * @see Rep#getDefaultRepository
213:             * @see Participant
214:             * @since 1.0
215:             */
216:            public static Participant getRepParticipant() {
217:                return Rep.getParticipant(DEFAULT_PARTICIPANT_NAME);
218:            }
219:
220:            /**
221:             * Retrieves the default object as a <code>Site</code> from the participant
222:             * that was returned by {@link #getRepParticipant}.
223:             *
224:             * @return the site instance; or
225:             * <p><code>null</code> if no "<code>ParticipantSite</code>" participant was
226:             * present in the default repository
227:             * @see #getRepParticipant
228:             * @see Participant#getObject
229:             * @since 1.0
230:             */
231:            public static Site getRepInstance() {
232:                Participant participant = getRepParticipant();
233:                if (null == participant) {
234:                    return null;
235:                }
236:
237:                return (Site) participant.getObject();
238:            }
239:
240:            /**
241:             * Retrieves the resource finder that was used to populate this site.
242:             *
243:             * @return this site's resource finder
244:             * @since 1.4
245:             */
246:            public ResourceFinder getResourceFinder() {
247:                return mData.mResourceFinder;
248:            }
249:
250:            /**
251:             * Retrieves the continuation manager that is used by this site.
252:             *
253:             * @return the site's contiuation manager
254:             * @since 1.5
255:             */
256:            public ContinuationManager getContinuationManager() {
257:                return mData.mContinuationManager;
258:            }
259:
260:            /**
261:             * Retrieves the collection of all the element IDs that are present in
262:             * this site.
263:             *
264:             * @return the collection of all the element IDs in this site
265:             * @since 1.0
266:             */
267:            public Collection<String> getIds() {
268:                return mData.mIdMapping.keySet();
269:            }
270:
271:            Collection<ElementInfo> getElementInfos() {
272:                return mData.mIdMapping.values();
273:            }
274:
275:            void addElementInfo(String id, ElementInfo elementInfo, String url)
276:                    throws EngineException {
277:                assert id != null;
278:                assert id.length() > 0;
279:                assert elementInfo != null;
280:
281:                if (mData.mIdMapping.containsKey(id)) {
282:                    throw new DuplicateElementIdException(id);
283:                }
284:                elementInfo.setId(id);
285:                mData.mIdMapping.put(id, elementInfo);
286:
287:                elementInfo.setSite(this );
288:
289:                if (url != null) {
290:                    // ensure that the root url always is '/' and not ''
291:                    if (0 == url.length()) {
292:                        url = "/";
293:                    }
294:
295:                    elementInfo.setUrl(url);
296:
297:                    mapElementId(id, url);
298:                }
299:            }
300:
301:            void mapElementId(String id, String url) throws EngineException {
302:                assert id != null;
303:                assert id.length() > 0;
304:                assert url != null;
305:
306:                ElementInfo element_info = mData.mIdMapping.get(id);
307:                if (null == element_info) {
308:                    throw new ElementIdNotFoundException(id);
309:                }
310:
311:                // ensure that the root url always is '/' and not ''
312:                if (0 == url.length()) {
313:                    url = "/";
314:                }
315:
316:                mData.mUrls = null;
317:                if (element_info.isPathInfoUsed()) {
318:                    List<ElementInfo> elements = mData.mPathinfoUrlMapping
319:                            .get(url);
320:                    if (null == elements) {
321:                        elements = new ArrayList<ElementInfo>();
322:                        mData.mPathinfoUrlMapping.put(url, elements);
323:                    }
324:
325:                    elements.add(element_info);
326:                } else {
327:                    if (mData.mUrlMapping.containsKey(url)) {
328:                        throw new UrlExistsException(id, url, mData.mUrlMapping
329:                                .get(url).getId());
330:                    }
331:
332:                    mData.mUrlMapping.put(url, element_info);
333:                }
334:            }
335:
336:            void addFallback(ElementInfo elementInfo, String url)
337:                    throws EngineException {
338:                assert elementInfo != null;
339:
340:                if (url != null) {
341:                    if (mData.mFallbackUrlMapping.containsKey(url)) {
342:                        throw new FallbackUrlExistsException(url);
343:                    }
344:                    mData.mFallbackUrlMapping.put(url, elementInfo);
345:                }
346:            }
347:
348:            /**
349:             * Searches which element would be used as a fallback for a particilar URL.
350:             *
351:             * @param url the URL for which a fallback should be found
352:             * @return the fallback element; or
353:             * <p><code>null</code> if no fallback is available for that URL
354:             * @since 1.0
355:             */
356:            public ElementInfo searchFallback(String url)
357:                    throws EngineException {
358:                if (null == url)
359:                    throw new IllegalArgumentException("url can't be null;");
360:
361:                checkModification();
362:
363:                String best_match = null;
364:                if (0 == url.length()) {
365:                    url = "/";
366:                }
367:
368:                for (String fallback_url : mData.mFallbackUrlMapping.keySet()) {
369:                    if (url.startsWith(fallback_url)
370:                            && (null == best_match || fallback_url.length() > best_match
371:                                    .length())) {
372:                        best_match = fallback_url;
373:                    }
374:                }
375:
376:                if (best_match != null) {
377:                    return mData.mFallbackUrlMapping.get(best_match);
378:                } else {
379:                    return null;
380:                }
381:            }
382:
383:            /**
384:             * Indicates whether a certain URL has a mapping in this site.
385:             *
386:             * @param url the URL that should be looked up
387:             * @return <code>true</code> if the URL corresponds to and element; or
388:             * <p><code>false</code> otherwise
389:             * @since 1.0
390:             */
391:            public boolean containsUrl(String url) {
392:                if (null == url)
393:                    throw new IllegalArgumentException("url can't be null;");
394:
395:                checkModification();
396:
397:                if (0 == url.length()) {
398:                    url = "/";
399:                }
400:
401:                if (mData.mUrlMapping.containsKey(url)) {
402:                    return true;
403:                }
404:
405:                if (url.length() > 0 && '/' == url.charAt(url.length() - 1)) {
406:                    String stripped_url = url.substring(0, url.length() - 1);
407:                    // if the url contains a dot in the last part, it shouldn't be
408:                    // seen as simulating a directory
409:                    if (stripped_url.lastIndexOf('.') <= stripped_url
410:                            .lastIndexOf('/')
411:                            && mData.mUrlMapping.containsKey(stripped_url)) {
412:                        return true;
413:                    }
414:                }
415:
416:                if (mData.mPathinfoUrlMapping.containsKey(url)) {
417:                    return true;
418:                }
419:
420:                return false;
421:            }
422:
423:            /**
424:             * Looks up the information of the element that is responsible for handling
425:             * a certain URL and pathinfo.
426:             *
427:             * @param url the URL that should be looked up
428:             * @param pathinfo the pathinfo that should be taken into account
429:             * @return the corresponding element information; or
430:             * <p><code>null</code> if the URL and pathinfo aren't registered in this site
431:             * @since 1.4
432:             */
433:            public ElementInfo resolveUrl(String url, String pathinfo)
434:                    throws EngineException {
435:                if (null == url)
436:                    throw new IllegalArgumentException("url can't be null;");
437:
438:                checkModification();
439:
440:                if (0 == url.length()) {
441:                    url = "/";
442:                }
443:
444:                ElementInfo result;
445:
446:                if (null == pathinfo) {
447:                    result = mData.mUrlMapping.get(url);
448:                    if (result != null) {
449:                        return result;
450:                    }
451:
452:                    if (url.length() > 0 && '/' == url.charAt(url.length() - 1)) {
453:                        String stripped_url = url
454:                                .substring(0, url.length() - 1);
455:                        // if the url contains a dot in the last part, it shouldn't be
456:                        // seen as simulating a directory
457:                        if (stripped_url.lastIndexOf('.') <= stripped_url
458:                                .lastIndexOf('/')) {
459:                            result = mData.mUrlMapping.get(stripped_url);
460:                            if (result != null) {
461:                                return result;
462:                            }
463:                        }
464:                    }
465:                }
466:
467:                result = resolvePathInfoUrl(url, pathinfo);
468:
469:                return result;
470:            }
471:
472:            /**
473:             * Looks for an element that corresponds to a particular request URL.
474:             * <p>
475:             * This method will determine the best element match by stepping up the path
476:             * segments. It will also look for fallback elements, cater for trailing
477:             * slashes, and figure out the correct pathinfo.
478:             * <p>
479:             * Basically, this is the method that is used by the <code>Gate</code> to
480:             * figure out which element to service when a request arrives.
481:             *
482:             * @param elementUrl the URL that will be used to search for the element
483:             *
484:             * @return an instance of <code>ElementToService</code> when an element match
485:             * was found; or
486:             * <p><code>null</code> if no suitable element could be found.
487:             * 
488:             * @since 1.6
489:             */
490:            public ElementToService findElementForRequest(String elementUrl) {
491:                // obtain the element info that mapped to the requested path info
492:                ElementInfo element_info = null;
493:                StringBuilder element_url_buffer = new StringBuilder(elementUrl);
494:                int element_url_location = -1;
495:                String element_path_info = "";
496:                String pathinfo = null;
497:                do {
498:                    // if a slash was found in the url, it was stripped away
499:                    // and thus the only urls that should match then are path info
500:                    // urls
501:                    if (element_url_location > -1) {
502:                        pathinfo = elementUrl.substring(element_url_location);
503:                    }
504:                    element_info = resolveUrl(element_url_buffer.toString(),
505:                            pathinfo);
506:
507:                    if (element_info != null) {
508:                        break;
509:                    }
510:
511:                    element_url_location = element_url_buffer.lastIndexOf("/");
512:                    if (-1 == element_url_location) {
513:                        break;
514:                    }
515:                    element_url_buffer.setLength(element_url_location);
516:                } while (element_url_location != -1);
517:
518:                // no target element, get the fallback element
519:                if (null == element_info) {
520:                    element_info = searchFallback(elementUrl);
521:                    if (null == element_info) {
522:                        return null;
523:                    }
524:                }
525:                // otherwise get the target element's path info
526:                else {
527:                    // only accept pathinfo if the element accepts it
528:                    if (!element_info.isPathInfoUsed()
529:                            && elementUrl.length() != element_url_buffer
530:                                    .length()) {
531:                        // check for a fallback element
532:                        element_info = searchFallback(elementUrl);
533:                        if (null == element_info) {
534:                            return null;
535:                        }
536:                    } else if (element_info.isPathInfoUsed()) {
537:                        // construct the element path info
538:                        element_path_info = elementUrl
539:                                .substring(element_url_buffer.length());
540:                        // always ensure that the path info starts with a slash
541:                        // this can not be present if the concerned element is
542:                        // an arrival for instance
543:                        if (!element_path_info.startsWith("/")) {
544:                            element_path_info = "/" + element_path_info;
545:                        }
546:                    }
547:                }
548:
549:                // if no element info was found, don't return an ElementToService match
550:                if (null == element_info) {
551:                    return null;
552:                }
553:
554:                return new ElementToService(element_info, element_path_info);
555:            }
556:
557:            private ElementInfo resolvePathInfoUrl(String url, String pathinfo)
558:                    throws EngineException {
559:                List<ElementInfo> elements = mData.mPathinfoUrlMapping.get(url);
560:                if (null == elements || 0 == elements.size()) {
561:                    return null;
562:                }
563:
564:                // if a pathinfo was provided, check the pathinfo mappings
565:                // for the first that matches
566:                if (pathinfo != null) {
567:                    for (ElementInfo element : elements) {
568:                        if (element.hasPathInfoMappings()) {
569:                            for (PathInfoMapping mapping : element
570:                                    .getPathInfoMappings()) {
571:                                Matcher matcher = mapping.getRegexp().matcher(
572:                                        pathinfo);
573:                                if (matcher.matches()) {
574:                                    return element;
575:                                }
576:                            }
577:                        }
578:                    }
579:                }
580:
581:                // return the first element that handles the url and doesn't have
582:                // any pathinfo mappings
583:                for (ElementInfo element : elements) {
584:                    if (!element.hasPathInfoMappings()
585:                            || PathInfoMode.LOOSE.equals(element
586:                                    .getPathInfoMode())) {
587:                        return element;
588:                    }
589:                }
590:
591:                return null;
592:            }
593:
594:            /**
595:             * Retrieves the collection of all the URLs that are present in this site.
596:             *
597:             * @return the collection of all the URLs in this site
598:             * @since 1.0
599:             */
600:            public Collection<String> getUrls() {
601:                if (null == mData.mUrls) {
602:                    ArrayList urls = new ArrayList<String>(mData.mUrlMapping
603:                            .keySet());
604:                    urls.addAll(mData.mPathinfoUrlMapping.keySet());
605:                    mData.mUrls = urls;
606:                }
607:
608:                return mData.mUrls;
609:            }
610:
611:            /**
612:             * Indicates whether an absolute element ID is present in the site.
613:             *
614:             * @param id the absolute element ID that should be looked up
615:             * @return <code>true</code> if the element ID could be found; or
616:             * <p><code>false</code> otherwise
617:             * @since 1.0
618:             */
619:            public boolean containsId(String id) {
620:                if (null == id)
621:                    throw new IllegalArgumentException("id can't be null.");
622:                if (0 == id.length())
623:                    throw new IllegalArgumentException("id can't be empty.");
624:
625:                return mData.mIdMapping.containsKey(id);
626:            }
627:
628:            /**
629:             * Retrieves the element information in this site that corresponds to
630:             * provided absolute element ID.
631:             *
632:             * @param id the absolute element ID that should be looked up
633:             * @return the corresponding element information; or
634:             * <p><code>null</code> if the absolute element ID couldn't be found
635:             * @since 1.0
636:             */
637:            public ElementInfo resolveId(String id) throws EngineException {
638:                return resolveId(id, null);
639:            }
640:
641:            /**
642:             * Retrieves the element information in this site that corresponds to
643:             * provided element ID.
644:             *
645:             * @param id the element ID that should be looked up
646:             * @param reference the element information that should be used as a
647:             * reference to look up the element information from when a relative ID
648:             * is provided
649:             * @return the corresponding element information; or
650:             * <p><code>null</code> if the element ID couldn't be found
651:             * @since 1.0
652:             */
653:            public ElementInfo resolveId(String id, ElementInfo reference)
654:                    throws EngineException {
655:                if (null == id)
656:                    throw new IllegalArgumentException("id can't be null.");
657:                if (0 == id.length())
658:                    throw new IllegalArgumentException("id can't be empty.");
659:
660:                checkModification();
661:
662:                String absolute_id = getCanonicalId(getAbsoluteId(id, reference));
663:
664:                return mData.mIdMapping.get(absolute_id);
665:            }
666:
667:            /**
668:             * Transforms the provided element ID into an absolute element ID.
669:             *
670:             * @param id the element ID that should be transformed
671:             * @param reference the element information that should be used as a
672:             * reference to look up the element information from when a relative ID
673:             * is provided
674:             * @return the absolute element ID that corresponds to the provided
675:             * element ID
676:             * @since 1.0
677:             */
678:            public static String getAbsoluteId(String id, ElementInfo reference) {
679:                if (null == id)
680:                    throw new IllegalArgumentException("id can't be null.");
681:                if (0 == id.length())
682:                    throw new IllegalArgumentException("id can't be empty.");
683:
684:                // resolve a relative element id
685:                if (!id.startsWith(".")) {
686:                    if (null == reference)
687:                        throw new IllegalArgumentException(
688:                                "reference can't be null for a relative element id.");
689:
690:                    String path_id = reference.getReferenceId().substring(0,
691:                            reference.getReferenceId().lastIndexOf(".") + 1);
692:                    StringBuilder absolute_id = new StringBuilder(path_id);
693:                    absolute_id.append(id);
694:                    id = absolute_id.toString();
695:                }
696:
697:                return id;
698:            }
699:
700:            /**
701:             * Transforms the provided element ID into a canonical ID without any
702:             * parent indicators.
703:             *
704:             * @param id the element ID that should be transformed
705:             * @return the canonical element ID that corresponds to the provided
706:             * element ID
707:             * @since 1.0
708:             */
709:            public static String getCanonicalId(String id) {
710:                if (null == id) {
711:                    return null;
712:                }
713:
714:                StringBuilder canonical_id = new StringBuilder();
715:
716:                StringTokenizer id_tok = new StringTokenizer(id, ".^", true);
717:                String token = null;
718:                int seperator_index = -1;
719:                while (id_tok.hasMoreTokens()) {
720:                    token = id_tok.nextToken();
721:                    if (token.equals(".")) {
722:                        // do nothing
723:                    } else if (token.equals("^")) {
724:                        // fold back to the previous element path part
725:                        // and don't go further than an empty string
726:                        seperator_index = canonical_id.lastIndexOf(".");
727:                        if (seperator_index != -1) {
728:                            canonical_id.setLength(seperator_index);
729:                        }
730:                    } else {
731:                        canonical_id.append(".");
732:                        canonical_id.append(token);
733:                    }
734:                }
735:
736:                // handle arrival elements
737:                if (id.endsWith(".")) {
738:                    canonical_id.append(".");
739:                }
740:
741:                return canonical_id.toString();
742:            }
743:
744:            /**
745:             * Adds the specified listener to receive site-related events.
746:             * If <code>listener</code> is null, no exception is thrown and no action
747:             * is performed.
748:             *
749:             * @param listener The site listener that will be added.
750:             * @see SiteListener
751:             * @see #removeListener(SiteListener)
752:             * @since 1.5
753:             */
754:            public void addListener(SiteListener listener) {
755:                if (null == listener)
756:                    return;
757:
758:                if (null == mListeners) {
759:                    mListeners = new HashSet<SiteListener>();
760:                }
761:                mListeners.add(listener);
762:            }
763:
764:            /**
765:             * Removes the site listener so that it no longer receives any events. This
766:             * method performs no function, nor does it throw an exception if the listener
767:             * specified by the argument was not previously added to this component or is
768:             * <code>null</code>.
769:             *
770:             * @param listener The site listener that will be removed.
771:             * @see SiteListener
772:             * @see #addListener(SiteListener)
773:             * @since 1.5
774:             */
775:            public void removeListener(SiteListener listener) {
776:                if (mListeners != null) {
777:                    mListeners.remove(listener);
778:                }
779:            }
780:
781:            /**
782:             * Notifies the registered listeners that one of the site's resources has
783:             * been detected as being modified.
784:             *
785:             * @see SiteListener
786:             * @since 1.5
787:             */
788:            public void fireModified() {
789:                if (mListeners != null && mListeners.size() > 0) {
790:                    for (SiteListener listener : mListeners) {
791:                        listener.modified(this );
792:                    }
793:                }
794:            }
795:
796:            Map<String, Method> getCachedOutputGetters(String elementId) {
797:                return mData.mOutputGettersCache.get(elementId);
798:            }
799:
800:            void putCachedOutputGetters(String elementId,
801:                    Map<String, Method> outputGetters) {
802:                synchronized (mData) {
803:                    mData.mOutputGettersCache.put(elementId, outputGetters);
804:                }
805:            }
806:
807:            Map<String, Method> getCachedOutbeanGetters(String elementId) {
808:                return mData.mOutbeanGettersCache.get(elementId);
809:            }
810:
811:            void putCachedOutbeanGetters(String elementId,
812:                    Map<String, Method> outbeanGetters) {
813:                synchronized (mData) {
814:                    mData.mOutbeanGettersCache.put(elementId, outbeanGetters);
815:                }
816:            }
817:
818:            Map<String, Method> getCachedOutcookieGetters(String elementId) {
819:                return mData.mOutcookieGettersCache.get(elementId);
820:            }
821:
822:            void putCachedOutcookieGetters(String elementId,
823:                    Map<String, Method> outcookieGetters) {
824:                synchronized (mData) {
825:                    mData.mOutcookieGettersCache.put(elementId,
826:                            outcookieGetters);
827:                }
828:            }
829:
830:            Map<String, Method> getCachedPropertySetters(String elementId) {
831:                return mData.mPropertySettersCache.get(elementId);
832:            }
833:
834:            void putCachedPropertySetters(String elementId,
835:                    Map<String, Method> propertySetters) {
836:                synchronized (mData) {
837:                    mData.mPropertySettersCache.put(elementId, propertySetters);
838:                }
839:            }
840:
841:            Map<String, Method> getCachedIncookieSetters(String elementId) {
842:                return mData.mIncookieSettersCache.get(elementId);
843:            }
844:
845:            void putCachedIncookieSetters(String elementId,
846:                    Map<String, Method> incookieSetters) {
847:                synchronized (mData) {
848:                    mData.mIncookieSettersCache.put(elementId, incookieSetters);
849:                }
850:            }
851:
852:            Map<String, Method> getCachedInputSetters(String elementId) {
853:                return mData.mInputSettersCache.get(elementId);
854:            }
855:
856:            void putCachedInputSetters(String elementId,
857:                    Map<String, Method> inputSetters) {
858:                synchronized (mData) {
859:                    mData.mInputSettersCache.put(elementId, inputSetters);
860:                }
861:            }
862:
863:            Map<String, Method> getCachedInbeanSetters(String elementId) {
864:                return mData.mInbeanSettersCache.get(elementId);
865:            }
866:
867:            void putCachedInbeanSetters(String elementId,
868:                    Map<String, Method> inbeanSetters) {
869:                synchronized (mData) {
870:                    mData.mInbeanSettersCache.put(elementId, inbeanSetters);
871:                }
872:            }
873:
874:            SubmissionSettersCache getSubmissionSettersCache(String elementId) {
875:                return mData.mSubmissionSettersCache.get(elementId);
876:            }
877:
878:            void putSubmissionSettersCache(String elementId,
879:                    SubmissionSettersCache submissionSettersCache) {
880:                synchronized (mData) {
881:                    mData.mSubmissionSettersCache.put(elementId,
882:                            submissionSettersCache);
883:                }
884:            }
885:
886:            private class SiteData {
887:                private Map<String, ElementInfo> mUrlMapping = new LinkedHashMap<String, ElementInfo>();
888:                private Map<String, List<ElementInfo>> mPathinfoUrlMapping = new LinkedHashMap<String, List<ElementInfo>>();
889:                private List<String> mUrls = null;
890:
891:                private Map<String, ElementInfo> mFallbackUrlMapping = new HashMap<String, ElementInfo>();
892:                private Map<String, ElementInfo> mIdMapping = new LinkedHashMap<String, ElementInfo>();
893:                private ContinuationManager<ElementSupport> mContinuationManager = new ContinuationManager<ElementSupport>(
894:                        EngineContinuationConfigRuntimeSingleton.INSTANCE);
895:
896:                private ResourceFinder mResourceFinder = null;
897:                private HashMap<UrlResource, Long> mResourceModificationTimes = null;
898:
899:                private Map<String, Map<String, Method>> mOutputGettersCache;
900:                private Map<String, Map<String, Method>> mOutbeanGettersCache;
901:                private Map<String, Map<String, Method>> mOutcookieGettersCache;
902:
903:                private Map<String, Map<String, Method>> mPropertySettersCache;
904:                private Map<String, Map<String, Method>> mIncookieSettersCache;
905:                private Map<String, Map<String, Method>> mInputSettersCache;
906:                private Map<String, Map<String, Method>> mInbeanSettersCache;
907:                private Map<String, SubmissionSettersCache> mSubmissionSettersCache;
908:
909:                SiteData() {
910:                    clearCaches();
911:                }
912:
913:                void clearCaches() {
914:                    if (TerracottaUtils.isTcPresent()) {
915:
916:                        mOutputGettersCache = new HashMap<String, Map<String, Method>>();
917:                        mOutbeanGettersCache = new HashMap<String, Map<String, Method>>();
918:                        mOutcookieGettersCache = new HashMap<String, Map<String, Method>>();
919:
920:                        mPropertySettersCache = new HashMap<String, Map<String, Method>>();
921:                        mIncookieSettersCache = new HashMap<String, Map<String, Method>>();
922:                        mInputSettersCache = new HashMap<String, Map<String, Method>>();
923:                        mInbeanSettersCache = new HashMap<String, Map<String, Method>>();
924:                        mSubmissionSettersCache = new HashMap<String, SubmissionSettersCache>();
925:                    } else {
926:                        mOutputGettersCache = new WeakHashMap<String, Map<String, Method>>();
927:                        mOutbeanGettersCache = new WeakHashMap<String, Map<String, Method>>();
928:                        mOutcookieGettersCache = new WeakHashMap<String, Map<String, Method>>();
929:
930:                        mPropertySettersCache = new WeakHashMap<String, Map<String, Method>>();
931:                        mIncookieSettersCache = new WeakHashMap<String, Map<String, Method>>();
932:                        mInputSettersCache = new WeakHashMap<String, Map<String, Method>>();
933:                        mInbeanSettersCache = new WeakHashMap<String, Map<String, Method>>();
934:                        mSubmissionSettersCache = new WeakHashMap<String, SubmissionSettersCache>();
935:                    }
936:                }
937:            }
938:        }
939:
940:        class SubmissionSettersCache {
941:            private Map<String, Map<String, Method>> mSubmissionparamSettersCache = new HashMap<String, Map<String, Method>>();
942:            private Map<String, Map<String, Method>> mSubmissionbeanSettersCache = new HashMap<String, Map<String, Method>>();
943:            private Map<String, Map<String, Method>> mUploadedfileSettersCache = new HashMap<String, Map<String, Method>>();
944:
945:            Map<String, Method> getCachedSubmissionparamSetters(
946:                    String submissionName) {
947:                return mSubmissionparamSettersCache.get(submissionName);
948:            }
949:
950:            synchronized void putCachedSubmissionparamSetters(
951:                    String submissionName,
952:                    Map<String, Method> submissionparamSetters) {
953:                mSubmissionparamSettersCache.put(submissionName,
954:                        submissionparamSetters);
955:            }
956:
957:            Map<String, Method> getCachedSubmissionbeanSetters(
958:                    String submissionName) {
959:                return mSubmissionbeanSettersCache.get(submissionName);
960:            }
961:
962:            synchronized void putCachedSubmissionbeanSetters(
963:                    String submissionName,
964:                    Map<String, Method> submissionbeanSetters) {
965:                mSubmissionbeanSettersCache.put(submissionName,
966:                        submissionbeanSetters);
967:            }
968:
969:            Map<String, Method> getCachedUploadedfileSetters(
970:                    String submissionName) {
971:                return mUploadedfileSettersCache.get(submissionName);
972:            }
973:
974:            synchronized void putCachedUploadedfileSetters(
975:                    String submissionName,
976:                    Map<String, Method> uploadedfileSetters) {
977:                mUploadedfileSettersCache.put(submissionName,
978:                        uploadedfileSetters);
979:            }
980:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.