Source Code Cross Referenced for HttpVariableMap.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 org.millstone.base.terminal.SystemError;
041:        import org.millstone.base.terminal.Terminal;
042:        import org.millstone.base.terminal.VariableOwner;
043:        import org.millstone.base.terminal.UploadStream;
044:
045:        import java.util.ArrayList;
046:        import java.util.Arrays;
047:        import java.util.HashMap;
048:        import java.util.HashSet;
049:        import java.util.Map;
050:        import java.util.Set;
051:        import java.util.List;
052:        import java.util.StringTokenizer;
053:        import java.util.Enumeration;
054:        import java.util.WeakHashMap;
055:        import java.io.IOException;
056:        import java.lang.ref.WeakReference;
057:
058:        import javax.servlet.http.HttpServletRequest;
059:        import java.util.LinkedList;
060:        import java.util.Iterator;
061:
062:        /**
063:         * Class implementing the MillStone WebAdapter variable mappings.
064:         * 
065:         * @author IT Mill Ltd.
066:         * @version 3.1.1
067:         * @since 3.0
068:         */
069:        public class HttpVariableMap {
070:
071:            // Id <-> (Owner,Name) mapping
072:            private Map idToNameMap = new HashMap();
073:            private Map idToTypeMap = new HashMap();
074:            private Map idToOwnerMap = new HashMap();
075:            private Map idToValueMap = new HashMap();
076:            private Map ownerToNameToIdMap = new WeakHashMap();
077:            private Object mapLock = new Object();
078:
079:            // Id generator
080:            private long lastId = 0;
081:
082:            /** Convert the string to a supported class */
083:            private static Object convert(Class type, String value)
084:                    throws java.lang.ClassCastException {
085:                try {
086:
087:                    // Boolean typed variables
088:                    if (type.equals(Boolean.class))
089:                        return new Boolean(!(value.equals("") || value
090:                                .equals("false")));
091:
092:                    // Integer typed variables
093:                    if (type.equals(Integer.class))
094:                        return new Integer(value.trim());
095:
096:                    // String typed variables
097:                    if (type.equals(String.class))
098:                        return value;
099:
100:                    throw new ClassCastException("Unsupported type: "
101:                            + type.getName());
102:                } catch (NumberFormatException e) {
103:                    return null;
104:                }
105:            }
106:
107:            /** Register a new variable.
108:             *
109:             * @return id to assigned for this variable.
110:             */
111:            public String registerVariable(String name, Class type,
112:                    Object value, VariableOwner owner) {
113:
114:                // Check that the type of the class is supported
115:                if (!(type.equals(Boolean.class) || type.equals(Integer.class)
116:                        || type.equals(String.class)
117:                        || type.equals(String[].class) || type
118:                        .equals(UploadStream.class)))
119:                    throw new SystemError("Unsupported variable type: "
120:                            + type.getClass());
121:
122:                synchronized (mapLock) {
123:
124:                    // Check if the variable is already mapped
125:                    HashMap nameToIdMap = (HashMap) ownerToNameToIdMap
126:                            .get(owner);
127:                    if (nameToIdMap == null) {
128:                        nameToIdMap = new HashMap();
129:                        ownerToNameToIdMap.put(owner, nameToIdMap);
130:                    }
131:                    String id = (String) nameToIdMap.get(name);
132:
133:                    if (id == null) {
134:                        // Generate new id and register it
135:                        id = "v" + String.valueOf(++lastId);
136:                        nameToIdMap.put(name, id);
137:                        idToOwnerMap.put(id, new WeakReference(owner));
138:                        idToNameMap.put(id, name);
139:                        idToTypeMap.put(id, type);
140:                    }
141:
142:                    idToValueMap.put(id, value);
143:
144:                    return id;
145:                }
146:            }
147:
148:            /** Unregisters a variable. */
149:            public void unregisterVariable(String name, VariableOwner owner) {
150:
151:                synchronized (mapLock) {
152:
153:                    // Get the id
154:                    HashMap nameToIdMap = (HashMap) ownerToNameToIdMap
155:                            .get(owner);
156:                    if (nameToIdMap == null)
157:                        return;
158:                    String id = (String) nameToIdMap.get(name);
159:                    if (id != null)
160:                        return;
161:
162:                    // Remove all the mappings
163:                    nameToIdMap.remove(name);
164:                    if (nameToIdMap.isEmpty())
165:                        ownerToNameToIdMap.remove(owner);
166:                    idToNameMap.remove(id);
167:                    idToTypeMap.remove(id);
168:                    idToValueMap.remove(id);
169:                    idToOwnerMap.remove(id);
170:
171:                }
172:            }
173:
174:            /**
175:             * @author IT Mill Ltd.
176:             * @version 3.1.1
177:             * @since 3.0
178:             */
179:            private class ParameterContainer {
180:
181:                /** Construct the mapping: listener to set of listened parameter names */
182:                private HashMap parameters = new HashMap();
183:
184:                /** Parameter values */
185:                private HashMap values = new HashMap();
186:
187:                /** Multipart parser used for parsing the request */
188:                private ServletMultipartRequest parser = null;
189:
190:                /** Name - Value mapping of parameters that are not variables */
191:                private HashMap nonVariables = new HashMap();
192:
193:                /** Create new parameter container and parse the parameters from the request using
194:                 * GET, POST and POST/MULTIPART parsing
195:                 */
196:                public ParameterContainer(HttpServletRequest req)
197:                        throws IOException {
198:                    // Parse GET / POST parameters
199:                    for (Enumeration e = req.getParameterNames(); e
200:                            .hasMoreElements();) {
201:                        String paramName = (String) e.nextElement();
202:                        String[] paramValues = req
203:                                .getParameterValues(paramName);
204:                        addParam(paramName, paramValues);
205:                    }
206:
207:                    // Parse multipart variables
208:                    try {
209:                        parser = new ServletMultipartRequest(req,
210:                                MultipartRequest.MAX_READ_BYTES);
211:                    } catch (IllegalArgumentException ignored) {
212:                        parser = null;
213:                    }
214:
215:                    if (parser != null) {
216:                        for (Enumeration e = parser.getFileParameterNames(); e
217:                                .hasMoreElements();) {
218:                            String paramName = (String) e.nextElement();
219:                            addParam(paramName, null);
220:                        }
221:                        for (Enumeration e = parser.getParameterNames(); e
222:                                .hasMoreElements();) {
223:                            String paramName = (String) e.nextElement();
224:                            Enumeration val = parser
225:                                    .getURLParameters(paramName);
226:
227:                            // Create a linked list from enumeration to calculate elements
228:                            LinkedList l = new LinkedList();
229:                            while (val.hasMoreElements())
230:                                l.addLast(val.nextElement());
231:
232:                            // String array event constructor
233:                            String[] s = new String[l.size()];
234:                            Iterator i = l.iterator();
235:                            for (int j = 0; j < s.length; j++)
236:                                s[j] = (String) i.next();
237:
238:                            addParam(paramName, s);
239:                        }
240:                    }
241:
242:                }
243:
244:                /** Add parameter to container */
245:                private void addParam(String name, String[] value) {
246:
247:                    // Support name="set:name=value" value="ignored" notation
248:                    if (name.startsWith("set:")) {
249:                        int equalsIndex = name.indexOf('=');
250:                        value[0] = name.substring(equalsIndex + 1, name
251:                                .length());
252:                        name = name.substring(4, equalsIndex);
253:                        String[] curVal = (String[]) values.get(name);
254:                        if (curVal != null) {
255:                            String[] newVal = new String[1 + curVal.length];
256:                            newVal[curVal.length] = value[0];
257:                            for (int i = 0; i < curVal.length; i++)
258:                                newVal[i] = curVal[i];
259:                            value = newVal;
260:
261:                            // Special case - if the set:-method is used for 
262:                            // declaring array of length 2, where either of the  
263:                            // following conditions are true:
264:                            //    - the both items are the same 
265:                            //    - the both items have the same length and 
266:                            //      - the items only differ on last character
267:                            //      - second last character is '.'
268:                            //      - last char of one string is 'x' and other is 'y'
269:                            // Browser is unporposely modifying the name. 
270:                            if (value.length == 2
271:                                    && value[0].length() == value[1].length()) {
272:                                boolean same = true;
273:                                for (int i = 0; i < value[0].length() - 1
274:                                        && same; i++)
275:                                    if (value[0].charAt(i) != value[1]
276:                                            .charAt(i))
277:                                        same = false;
278:                                if (same
279:                                        && ((value[0]
280:                                                .charAt(value[0].length() - 1) == 'x' && value[1]
281:                                                .charAt(value[1].length() - 1) == 'y') || (value[0]
282:                                                .charAt(value[0].length() - 1) == 'y' && value[1]
283:                                                .charAt(value[1].length() - 1) == 'x'))) {
284:                                    value = new String[] { value[0].substring(
285:                                            0, value[1].length() - 2) };
286:                                } else if (same && value[0].equals(value[1]))
287:                                    value = new String[] { value[0] };
288:                            }
289:
290:                            // Special case - if the set:-method is used for 
291:                            // declaring array of length 3, where all of the 
292:                            // following conditions are true:
293:                            //    - two last items  have the same length
294:                            //    - the first item is 2 chars shorter
295:                            //    - the longer items only differ on last character
296:                            //    - the shortest item is a prefix of the longer ones
297:                            //    - second last character of longer ones is '.'
298:                            //    - last char of one long string is 'x' and other is 'y'
299:                            // Browser is unporposely modifying the name. (Mozilla, Firefox, ..)
300:                            if (value.length == 3
301:                                    && value[1].length() == value[2].length()
302:                                    && value[0].length() + 2 == value[1]
303:                                            .length()) {
304:                                boolean same = true;
305:                                for (int i = 0; i < value[1].length() - 1
306:                                        && same; i++)
307:                                    if (value[2].charAt(i) != value[1]
308:                                            .charAt(i))
309:                                        same = false;
310:                                for (int i = 0; i < value[0].length() && same; i++)
311:                                    if (value[0].charAt(i) != value[1]
312:                                            .charAt(i))
313:                                        same = false;
314:                                if (same
315:                                        && (value[2]
316:                                                .charAt(value[2].length() - 1) == 'x' && value[1]
317:                                                .charAt(value[1].length() - 1) == 'y')
318:                                        || (value[2]
319:                                                .charAt(value[2].length() - 1) == 'y' && value[1]
320:                                                .charAt(value[1].length() - 1) == 'x')) {
321:                                    value = new String[] { value[0] };
322:                                }
323:                            }
324:
325:                        }
326:                    }
327:
328:                    // Support for setting arrays in format
329:                    // set-array:name=value1,value2,value3,...
330:                    else if (name.startsWith("set-array:")) {
331:                        int equalsIndex = name.indexOf('=');
332:                        if (equalsIndex < 0)
333:                            return;
334:
335:                        StringTokenizer commalist = new StringTokenizer(name
336:                                .substring(equalsIndex + 1), ",");
337:                        name = name.substring(10, equalsIndex);
338:                        String[] curVal = (String[]) values.get(name);
339:                        ArrayList elems = new ArrayList();
340:
341:                        // Add old values if present.
342:                        if (curVal != null) {
343:                            for (int i = 0; i < curVal.length; i++)
344:                                elems.add(curVal[i]);
345:                        }
346:                        while (commalist.hasMoreTokens()) {
347:                            String token = commalist.nextToken();
348:                            if (token != null && token.length() > 0)
349:                                elems.add(token);
350:                        }
351:                        value = new String[elems.size()];
352:                        for (int i = 0; i < value.length; i++)
353:                            value[i] = (String) elems.get(i);
354:
355:                    }
356:
357:                    // Support name="array:name" value="val1,val2,val3" notation
358:                    // All the empty elements are ignored
359:                    else if (name.startsWith("array:")) {
360:
361:                        name = name.substring(6);
362:                        StringTokenizer commalist = new StringTokenizer(
363:                                value[0], ",");
364:                        String[] curVal = (String[]) values.get(name);
365:                        ArrayList elems = new ArrayList();
366:
367:                        // Add old values if present.
368:                        if (curVal != null) {
369:                            for (int i = 0; i < curVal.length; i++)
370:                                elems.add(curVal[i]);
371:                        }
372:                        while (commalist.hasMoreTokens()) {
373:                            String token = commalist.nextToken();
374:                            if (token != null && token.length() > 0)
375:                                elems.add(token);
376:                        }
377:                        value = new String[elems.size()];
378:                        for (int i = 0; i < value.length; i++)
379:                            value[i] = (String) elems.get(i);
380:                    }
381:
382:                    // Support declaring variables with name="declare:name"
383:                    else if (name.startsWith("declare:")) {
384:                        name = name.substring(8);
385:                        value = (String[]) values.get(name);
386:                        if (value == null)
387:                            value = new String[0];
388:                    }
389:
390:                    // Get the owner
391:                    WeakReference ref = (WeakReference) idToOwnerMap.get(name);
392:                    VariableOwner owner = null;
393:                    if (ref != null)
394:                        owner = (VariableOwner) ref.get();
395:
396:                    // Add the parameter to mapping only if they have owners
397:                    if (owner != null) {
398:                        Set p = (Set) parameters.get(owner);
399:                        if (p == null)
400:                            parameters.put(owner, p = new HashSet());
401:                        p.add(name);
402:                        if (value != null)
403:                            values.put(name, value);
404:                    }
405:
406:                    // If the owner can not be found
407:                    else {
408:
409:                        // If parameter has been mapped before, remove the old owner mapping
410:                        if (ref != null) {
411:
412:                            // The owner has been destroyed, so we remove the mappings
413:                            idToNameMap.remove(name);
414:                            idToOwnerMap.remove(name);
415:                            idToTypeMap.remove(name);
416:                            idToValueMap.remove(name);
417:                        }
418:
419:                        // Add the parameter to set of non-variables
420:                        nonVariables.put(name, value);
421:                    }
422:
423:                }
424:
425:                /** Get the set of all parameters connected to given variable owner */
426:                public Set getParameters(VariableOwner owner) {
427:                    if (owner == null)
428:                        return null;
429:                    return (Set) parameters.get(owner);
430:                }
431:
432:                /** Get the set of all variable owners owning parameters in this request */
433:                public Set getOwners() {
434:                    return parameters.keySet();
435:                }
436:
437:                /** Get the value of a parameter */
438:                public String[] getValue(String parameterName) {
439:                    return (String[]) values.get(parameterName);
440:                }
441:
442:                /** Get the servlet multipart parser */
443:                public ServletMultipartRequest getParser() {
444:                    return parser;
445:                }
446:
447:                /** Get the name - value[] mapping of non variable paramteres */
448:                public Map getNonVariables() {
449:                    return nonVariables;
450:                }
451:            }
452:
453:            /** Handle all variable changes in this request.
454:             *  @param req Http request to handle
455:             *  @param listeners If the list is non null, only the listed listeners are
456:             *  served. Otherwise all the listeners are served.
457:             *  @return Name to Value[] mapping of unhandled variables
458:             */
459:            public Map handleVariables(HttpServletRequest req,
460:                    Terminal.ErrorListener errorListener) throws IOException {
461:
462:                // Get the parameters
463:                ParameterContainer parcon = new ParameterContainer(req);
464:
465:                // Sort listeners to dependency order
466:                List listeners = getDependencySortedListenerList(parcon
467:                        .getOwners());
468:
469:                // Handle all parameters for all listeners
470:                while (!listeners.isEmpty()) {
471:                    VariableOwner listener = (VariableOwner) listeners
472:                            .remove(0);
473:                    boolean changed = false; // Has any of this owners variabes changed
474:                    // Handle all parameters for listener
475:                    Set params = parcon.getParameters(listener);
476:                    if (params != null) { // Name value mapping
477:                        Map variables = new HashMap();
478:                        for (Iterator pi = params.iterator(); pi.hasNext();) {
479:                            // Get the name of the parameter
480:                            String param = (String) pi.next();
481:                            // Extract more information about the parameter
482:                            String varName = (String) idToNameMap.get(param);
483:                            Class varType = (Class) idToTypeMap.get(param);
484:                            Object varOldValue = idToValueMap.get(param);
485:                            if (varName == null || varType == null)
486:                                Log
487:                                        .warn("VariableMap: No variable found for parameter "
488:                                                + param
489:                                                + " ("
490:                                                + varName
491:                                                + ","
492:                                                + listener + ")");
493:                            else {
494:
495:                                ServletMultipartRequest parser = parcon
496:                                        .getParser();
497:
498:                                // Upload events
499:                                if (varType.equals(UploadStream.class)) {
500:                                    if (parser != null
501:                                            && parser.getFileParameter(param,
502:                                                    MultipartRequest.FILENAME) != null) {
503:                                        String filename = (String) parser
504:                                                .getFileParameter(
505:                                                        param,
506:                                                        MultipartRequest.FILENAME);
507:                                        String contentType = (String) parser
508:                                                .getFileParameter(
509:                                                        param,
510:                                                        MultipartRequest.CONTENT_TYPE);
511:                                        UploadStream upload = new HttpUploadStream(
512:                                                varName,
513:                                                parser.getFileContents(param),
514:                                                filename, contentType);
515:                                        variables.put(varName, upload);
516:                                        changed = true;
517:                                    }
518:                                }
519:
520:                                // Normal variable change events
521:                                else {
522:                                    // First try to parse the event without multipart
523:                                    String[] values = parcon.getValue(param);
524:                                    if (values != null) {
525:
526:                                        if (varType.equals(String[].class)) {
527:                                            variables.put(varName, values);
528:                                            changed |= (!Arrays.equals(values,
529:                                                    (String[]) varOldValue));
530:                                        } else {
531:                                            try {
532:                                                if (values.length == 1) {
533:                                                    Object val = convert(
534:                                                            varType, values[0]);
535:                                                    variables.put(varName, val);
536:                                                    changed |= ((val == null && varOldValue != null) || (val != null && !val
537:                                                            .equals(varOldValue)));
538:                                                } else if (values.length == 0
539:                                                        && varType
540:                                                                .equals(Boolean.class)) {
541:                                                    Object val = new Boolean(
542:                                                            false);
543:                                                    variables.put(varName, val);
544:                                                    changed |= (!val
545:                                                            .equals(varOldValue));
546:                                                } else {
547:                                                    Log
548:                                                            .warn("Empty variable '"
549:                                                                    + varName
550:                                                                    + "' of type "
551:                                                                    + varType
552:                                                                            .toString());
553:                                                }
554:
555:                                            } catch (java.lang.ClassCastException e) {
556:                                                Log
557:                                                        .except(
558:                                                                "WebVariableMap conversion exception",
559:                                                                e);
560:                                                errorListener
561:                                                        .terminalError(new TerminalErrorImpl(
562:                                                                e));
563:                                            }
564:                                        }
565:                                    }
566:                                }
567:                            }
568:                        }
569:
570:                        // Do the valuechange if the listener is enabled
571:                        if (listener.isEnabled() && changed) {
572:                            try {
573:                                listener.changeVariables(req, variables);
574:                            } catch (Throwable t) {
575:                                // Notify the error listener
576:                                errorListener
577:                                        .terminalError(new VariableOwnerErrorImpl(
578:                                                listener, t));
579:                            }
580:                        }
581:                    }
582:                }
583:
584:                return parcon.getNonVariables();
585:            }
586:
587:            /** Implementation of VariableOwner.Error interface. */
588:            public class TerminalErrorImpl implements  Terminal.ErrorEvent {
589:                private Throwable throwable;
590:
591:                private TerminalErrorImpl(Throwable throwable) {
592:                    this .throwable = throwable;
593:                }
594:
595:                /**
596:                 * @see org.millstone.base.terminal.Terminal.ErrorEvent#getThrowable()
597:                 */
598:                public Throwable getThrowable() {
599:                    return this .throwable;
600:                }
601:
602:            }
603:
604:            /** Implementation of VariableOwner.Error interface. */
605:            public class VariableOwnerErrorImpl extends TerminalErrorImpl
606:                    implements  VariableOwner.ErrorEvent {
607:
608:                private VariableOwner owner;
609:
610:                private VariableOwnerErrorImpl(VariableOwner owner,
611:                        Throwable throwable) {
612:                    super (throwable);
613:                    this .owner = owner;
614:                }
615:
616:                /**
617:                 * @see org.millstone.base.terminal.VariableOwner.ErrorEvent#getVariableOwner()
618:                 */
619:                public VariableOwner getVariableOwner() {
620:                    return this .owner;
621:                }
622:
623:            }
624:
625:            /** Resolve the VariableOwners needed from the request and sort
626:             * them to assure that the dependencies are met (as well as possible).
627:             * @return List of variable list changers, that are needed for handling
628:             * all the variables in the request
629:             * @param req request to be handled
630:             * @param parser multipart parser for the request
631:             */
632:            private List getDependencySortedListenerList(Set listeners) {
633:
634:                LinkedList resultNormal = new LinkedList();
635:                LinkedList resultImmediate = new LinkedList();
636:
637:                // Go trough the listeners and either add them to result or resolve
638:                // their dependencies
639:                HashMap deepdeps = new HashMap();
640:                LinkedList unresolved = new LinkedList();
641:                for (Iterator li = listeners.iterator(); li.hasNext();) {
642:
643:                    VariableOwner listener = (VariableOwner) li.next();
644:                    if (listener != null) {
645:                        Set dependencies = listener.getDirectDependencies();
646:
647:                        // The listeners with no dependencies are added to the front of the
648:                        // list directly
649:                        if (dependencies == null || dependencies.isEmpty()) {
650:                            if (listener.isImmediate())
651:                                resultImmediate.addFirst(listener);
652:                            else
653:                                resultNormal.addFirst(listener);
654:                        }
655:
656:                        // Resolve deep dependencies for the listeners with dependencies
657:                        // (the listeners will be added to the end of results in correct
658:                        // dependency order later). Also the dependencies of all the
659:                        // depended listeners are resolved.
660:                        else if (deepdeps.get(listener) == null) {
661:
662:                            // Set the fifo for unresolved parents to contain only the
663:                            // listener to be resolved
664:                            unresolved.clear();
665:                            unresolved.add(listener);
666:
667:                            // Resolve dependencies
668:                            HashSet tmpdeepdeps = new HashSet();
669:                            while (!unresolved.isEmpty()) {
670:
671:                                VariableOwner l = (VariableOwner) unresolved
672:                                        .removeFirst();
673:                                if (!tmpdeepdeps.contains(l)) {
674:                                    tmpdeepdeps.add(l);
675:                                    if (deepdeps.containsKey(l)) {
676:                                        tmpdeepdeps.addAll((Set) deepdeps
677:                                                .get(l));
678:                                    } else {
679:                                        Set deps = l.getDirectDependencies();
680:                                        if (deps != null && !deps.isEmpty())
681:                                            for (Iterator di = deps.iterator(); di
682:                                                    .hasNext();) {
683:                                                Object d = di.next();
684:                                                if (d != null
685:                                                        && !tmpdeepdeps
686:                                                                .contains(d))
687:                                                    unresolved.addLast(d);
688:                                            }
689:                                    }
690:                                }
691:                            }
692:
693:                            tmpdeepdeps.remove(listener);
694:                            deepdeps.put(listener, tmpdeepdeps);
695:                        }
696:                    }
697:                }
698:
699:                // Add the listeners with dependencies in sane order to the result
700:                for (Iterator li = deepdeps.keySet().iterator(); li.hasNext();) {
701:                    VariableOwner l = (VariableOwner) li.next();
702:                    boolean immediate = l.isImmediate();
703:
704:                    // Add each listener after the last depended listener already in
705:                    // the list
706:                    int index = -1;
707:                    for (Iterator di = ((Set) deepdeps.get(l)).iterator(); di
708:                            .hasNext();) {
709:                        int k;
710:                        Object depended = di.next();
711:                        if (immediate) {
712:                            k = resultImmediate.lastIndexOf(depended);
713:                        } else {
714:                            k = resultNormal.lastIndexOf(depended);
715:                        }
716:                        if (k > index)
717:                            index = k;
718:                    }
719:                    if (immediate) {
720:                        resultImmediate.add(index + 1, l);
721:                    } else {
722:                        resultNormal.add(index + 1, l);
723:                    }
724:                }
725:
726:                // Append immediate listeners to normal listeners
727:                // This way the normal handlers are always called before
728:                // immediate ones
729:                resultNormal.addAll(resultImmediate);
730:                return resultNormal;
731:            }
732:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.