Source Code Cross Referenced for AbstractEnvironment.java in  » Web-Framework » cocoon » org » apache » cocoon » environment » 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 » cocoon » org.apache.cocoon.environment 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.environment;
018:
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.io.OutputStream;
022:        import java.lang.reflect.Method;
023:        import java.net.MalformedURLException;
024:        import java.util.Enumeration;
025:        import java.util.HashMap;
026:        import java.util.Map;
027:
028:        import org.apache.avalon.framework.CascadingRuntimeException;
029:        import org.apache.avalon.framework.component.ComponentException;
030:        import org.apache.avalon.framework.component.ComponentManager;
031:        import org.apache.avalon.framework.logger.AbstractLogEnabled;
032:        import org.apache.cocoon.Constants;
033:        import org.apache.cocoon.ProcessingException;
034:        import org.apache.cocoon.components.CocoonComponentManager;
035:        import org.apache.cocoon.components.source.SourceUtil;
036:        import org.apache.cocoon.util.BufferedOutputStream;
037:        import org.apache.cocoon.util.ClassUtils;
038:        import org.apache.cocoon.util.Deprecation;
039:        import org.apache.commons.collections.iterators.IteratorEnumeration;
040:        import org.apache.excalibur.source.SourceException;
041:        import org.xml.sax.SAXException;
042:
043:        /**
044:         * Base class for any environment
045:         *
046:         * @author <a href="mailto:bluetkemeier@s-und-n.de">Bj&ouml;rn L&uuml;tkemeier</a>
047:         * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
048:         * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
049:         * @version $Id: AbstractEnvironment.java 433543 2006-08-22 06:22:54Z crossley $
050:         */
051:        public abstract class AbstractEnvironment extends AbstractLogEnabled
052:                implements  Environment {
053:
054:            /** The current uri in progress */
055:            protected String uris;
056:
057:            /** The current prefix to strip off from the request uri */
058:            protected StringBuffer prefix = new StringBuffer();
059:
060:            /** The View requested */
061:            protected String view;
062:
063:            /** The Action requested */
064:            protected String action;
065:
066:            /** The Context path */
067:            protected String context;
068:
069:            /** The context path stored temporarily between constructor and initComponents */
070:            private String tempInitContext;
071:
072:            /** The root context path */
073:            protected String rootContext;
074:
075:            /** The servlet object model */
076:            protected HashMap objectModel;
077:
078:            /** The real source resolver */
079:            protected org.apache.excalibur.source.SourceResolver sourceResolver;
080:
081:            /** The component manager */
082:            protected ComponentManager manager;
083:
084:            /** The attributes */
085:            private Map attributes = new HashMap();
086:
087:            /** The secure Output Stream */
088:            protected BufferedOutputStream secureOutputStream;
089:
090:            /** The real output stream */
091:            protected OutputStream outputStream;
092:
093:            /** The AvalonToCocoonSourceWrapper (this is for the deprecated support) */
094:            static protected Method avalonToCocoonSourceWrapper;
095:
096:            /** Do we have our components ? */
097:            protected boolean initializedComponents = false;
098:
099:            /**
100:             * Constructs the abstract environment
101:             */
102:            public AbstractEnvironment(String uri, String view, File file)
103:                    throws MalformedURLException {
104:                this (uri, view, file, null);
105:            }
106:
107:            /**
108:             * Constructs the abstract environment
109:             */
110:            public AbstractEnvironment(String uri, String view, File file,
111:                    String action) throws MalformedURLException {
112:                this (uri, view, file.toURL().toExternalForm(), action);
113:            }
114:
115:            /**
116:             * Constructs the abstract environment
117:             */
118:            public AbstractEnvironment(String uri, String view, String context,
119:                    String action) throws MalformedURLException {
120:                this .uris = uri;
121:                this .view = view;
122:                this .tempInitContext = context;
123:                this .action = action;
124:                this .objectModel = new HashMap();
125:            }
126:
127:            /**
128:             * Allow implementations to set view later than in super() constructor.
129:             * View can be set only once, and should be set in implementation's constructor.
130:             */
131:            protected void setView(String view) {
132:                if (this .view != null) {
133:                    throw new IllegalStateException(
134:                            "View was already set on this environment");
135:                }
136:                this .view = view;
137:            }
138:
139:            /**
140:             * Allow implementations to set action later than in super() constructor
141:             * Action can be set only once, and should be set in implementation's constructor.
142:             */
143:            protected void setAction(String action) {
144:                if (this .action != null) {
145:                    throw new IllegalStateException(
146:                            "Action was already set on this environment");
147:                }
148:                this .action = action;
149:            }
150:
151:            /**
152:             * Helper method to extract the view name from the request.
153:             */
154:            protected static String extractView(Request request) {
155:                return request.getParameter(Constants.VIEW_PARAM);
156:            }
157:
158:            /**
159:             * Helper method to extract the action name from the request.
160:             */
161:            protected static String extractAction(Request req) {
162:                String action = req.getParameter(Constants.ACTION_PARAM);
163:                if (action != null) {
164:                    /* TC: still support the deprecated syntax */
165:                    return action;
166:                } else {
167:                    for (Enumeration e = req.getParameterNames(); e
168:                            .hasMoreElements();) {
169:                        String name = (String) e.nextElement();
170:                        if (name.startsWith(Constants.ACTION_PARAM_PREFIX)) {
171:                            if (name.endsWith(".x") || name.endsWith(".y")) {
172:                                return name.substring(
173:                                        Constants.ACTION_PARAM_PREFIX.length(),
174:                                        name.length() - 2);
175:                            } else {
176:                                return name
177:                                        .substring(Constants.ACTION_PARAM_PREFIX
178:                                                .length());
179:                            }
180:                        }
181:                    }
182:                    return null;
183:                }
184:            }
185:
186:            // Sitemap methods
187:
188:            /**
189:             * Returns the uri in progress. The prefix is stripped off
190:             */
191:            public String getURI() {
192:                return this .uris;
193:            }
194:
195:            /**
196:             * Get the Root Context
197:             */
198:            public String getRootContext() {
199:                if (!this .initializedComponents) {
200:                    this .initComponents();
201:                }
202:                return this .rootContext;
203:            }
204:
205:            /**
206:             * Get the current Context
207:             */
208:            public String getContext() {
209:                if (!this .initializedComponents) {
210:                    this .initComponents();
211:                }
212:                return this .context;
213:            }
214:
215:            /**
216:             * Get the prefix of the URI in progress
217:             */
218:            public String getURIPrefix() {
219:                return this .prefix.toString();
220:            }
221:
222:            /**
223:             * Set the prefix of the URI in progress
224:             */
225:            protected void setURIPrefix(String prefix) {
226:                if (getLogger().isDebugEnabled()) {
227:                    getLogger().debug(
228:                            "Set the URI Prefix (OLD=" + getURIPrefix()
229:                                    + ", NEW=" + prefix + ")");
230:                }
231:                this .prefix = new StringBuffer(prefix);
232:            }
233:
234:            /**
235:             * Set the context.
236:             */
237:            protected void setContext(String context) {
238:                this .context = context;
239:            }
240:
241:            /**
242:             * Set the context. This is similar to changeContext()
243:             * except that it is absolute.
244:             */
245:            public void setContext(String prefix, String uri, String context) {
246:                this .setContext(context);
247:                this .setURIPrefix(prefix == null ? "" : prefix);
248:                this .uris = uri;
249:                if (getLogger().isDebugEnabled()) {
250:                    getLogger().debug("Reset context to " + this .context);
251:                }
252:            }
253:
254:            /**
255:             * Adds an prefix to the overall stripped off prefix from the request uri
256:             */
257:            public void changeContext(String newPrefix, String newContext)
258:                    throws IOException {
259:                if (!this .initializedComponents) {
260:                    this .initComponents();
261:                }
262:
263:                if (getLogger().isDebugEnabled()) {
264:                    getLogger().debug("Changing Cocoon context");
265:                    getLogger().debug(
266:                            "  from context(" + this .context + ") and prefix("
267:                                    + this .prefix + ")");
268:                    getLogger().debug(
269:                            "  to context(" + newContext + ") and prefix("
270:                                    + newPrefix + ")");
271:                    getLogger().debug("  at URI " + this .uris);
272:                }
273:
274:                int l = newPrefix.length();
275:                if (l >= 1) {
276:                    if (!this .uris.startsWith(newPrefix)) {
277:                        String message = "The current URI (" + this .uris
278:                                + ") doesn't start with given prefix ("
279:                                + newPrefix + ")";
280:                        getLogger().error(message);
281:                        throw new RuntimeException(message);
282:                    }
283:                    this .prefix.append(newPrefix);
284:                    this .uris = this .uris.substring(l);
285:
286:                    // check for a slash at the beginning to avoid problems with subsitemaps
287:                    if (this .uris.startsWith("/")) {
288:                        this .uris = this .uris.substring(1);
289:                        this .prefix.append('/');
290:                    }
291:                }
292:
293:                if (this .context.startsWith("zip:")) {
294:                    // if the resource is zipped into a war file (e.g. Weblogic temp deployment)
295:                    // FIXME (VG): Is this still required? Better to unify both cases.
296:                    if (getLogger().isDebugEnabled()) {
297:                        getLogger().debug(
298:                                "Base context is zip: " + this .context);
299:                    }
300:
301:                    org.apache.excalibur.source.Source source = null;
302:                    try {
303:                        source = this .sourceResolver.resolveURI(this .context
304:                                + newContext);
305:                        this .context = source.getURI();
306:                    } finally {
307:                        this .sourceResolver.release(source);
308:                    }
309:                } else if (newContext.length() > 0) {
310:                    String sContext;
311:                    // if we got a absolute context or one with a protocol resolve it
312:                    if (newContext.charAt(0) == '/') {
313:                        // context starts with the '/' - absolute file URL
314:                        sContext = "file:" + newContext;
315:                    } else if (newContext.indexOf(':') > 1) {
316:                        // context have ':' - absolute URL
317:                        sContext = newContext;
318:                    } else {
319:                        // context is relative to old one
320:                        sContext = this .context + '/' + newContext;
321:                    }
322:
323:                    // Cut the file name part from context (if present)
324:                    int i = sContext.lastIndexOf('/');
325:                    if (i != -1 && i + 1 < sContext.length()) {
326:                        sContext = sContext.substring(0, i + 1);
327:                    }
328:
329:                    org.apache.excalibur.source.Source source = null;
330:                    try {
331:                        source = this .sourceResolver.resolveURI(sContext);
332:                        this .context = source.getURI();
333:                    } finally {
334:                        this .sourceResolver.release(source);
335:                    }
336:                }
337:
338:                if (getLogger().isDebugEnabled()) {
339:                    getLogger().debug("New context is " + this .context);
340:                }
341:            }
342:
343:            public void globalRedirect(boolean sessionmode, String newURL)
344:                    throws IOException {
345:                redirect(sessionmode, newURL);
346:            }
347:
348:            // Request methods
349:
350:            /**
351:             * Returns the request view
352:             */
353:            public String getView() {
354:                return this .view;
355:            }
356:
357:            /**
358:             * Returns the request action
359:             */
360:            public String getAction() {
361:                return this .action;
362:            }
363:
364:            // Response methods
365:
366:            /**
367:             * Set a status code
368:             */
369:            public void setStatus(int statusCode) {
370:            }
371:
372:            // Object model method
373:
374:            /**
375:             * Returns a Map containing environment specific objects
376:             */
377:            public Map getObjectModel() {
378:                return this .objectModel;
379:            }
380:
381:            /**
382:             * Resolve an entity.
383:             * @deprecated Use the resolveURI methods instead
384:             */
385:            public Source resolve(String systemId) throws ProcessingException,
386:                    SAXException, IOException {
387:                Deprecation.logger
388:                        .warn("The method SourceResolver.resolve(String) is "
389:                                + "deprecated. Use resolveURI(String) instead.");
390:                if (!this .initializedComponents) {
391:                    initComponents();
392:                }
393:
394:                if (getLogger().isDebugEnabled()) {
395:                    getLogger().debug(
396:                            "Resolving '" + systemId + "' in context '"
397:                                    + this .context + "'");
398:                }
399:
400:                if (systemId == null) {
401:                    throw new SAXException("Invalid System ID");
402:                }
403:
404:                // get the wrapper class - we don't want to import the wrapper directly
405:                // to avoid a direct dependency from the core to the deprecation package
406:                Class clazz;
407:                try {
408:                    clazz = ClassUtils
409:                            .loadClass("org.apache.cocoon.components.source.impl.AvalonToCocoonSourceInvocationHandler");
410:                } catch (Exception e) {
411:                    throw new ProcessingException(
412:                            "The deprecated resolve() method of the environment was called."
413:                                    + "Please either update your code to use the new resolveURI() method or"
414:                                    + " install the deprecation support.", e);
415:                }
416:
417:                if (null == avalonToCocoonSourceWrapper) {
418:                    synchronized (getClass()) {
419:                        try {
420:                            avalonToCocoonSourceWrapper = clazz
421:                                    .getDeclaredMethod(
422:                                            "createProxy",
423:                                            new Class[] {
424:                                                    ClassUtils
425:                                                            .loadClass("org.apache.excalibur.source.Source"),
426:                                                    ClassUtils
427:                                                            .loadClass("org.apache.excalibur.source.SourceResolver"),
428:                                                    ClassUtils
429:                                                            .loadClass(Environment.class
430:                                                                    .getName()),
431:                                                    ClassUtils
432:                                                            .loadClass(ComponentManager.class
433:                                                                    .getName()) });
434:                        } catch (Exception e) {
435:                            throw new ProcessingException(
436:                                    "The deprecated resolve() method of the environment was called."
437:                                            + "Please either update your code to use the new resolveURI() method or"
438:                                            + " install the deprecation support.",
439:                                    e);
440:                        }
441:                    }
442:                }
443:
444:                try {
445:                    org.apache.excalibur.source.Source source = resolveURI(systemId);
446:                    Source wrappedSource = (Source) avalonToCocoonSourceWrapper
447:                            .invoke(clazz, new Object[] { source,
448:                                    this .sourceResolver, this , this .manager });
449:                    return wrappedSource;
450:                } catch (SourceException se) {
451:                    throw SourceUtil.handle(se);
452:                } catch (Exception e) {
453:                    throw new ProcessingException(
454:                            "Unable to create source wrapper.", e);
455:                }
456:            }
457:
458:            /**
459:             * Check if the response has been modified since the same
460:             * "resource" was requested.
461:             * The caller has to test if it is really the same "resource"
462:             * which is requested.
463:             * @return true if the response is modified or if the
464:             *         environment is not able to test it
465:             */
466:            public boolean isResponseModified(long lastModified) {
467:                return true; // always modified
468:            }
469:
470:            /**
471:             * Mark the response as not modified.
472:             */
473:            public void setResponseIsNotModified() {
474:                // does nothing
475:            }
476:
477:            public Object getAttribute(String name) {
478:                return this .attributes.get(name);
479:            }
480:
481:            public void setAttribute(String name, Object value) {
482:                this .attributes.put(name, value);
483:            }
484:
485:            protected boolean hasAttribute(String name) {
486:                return this .attributes.containsKey(name);
487:            }
488:
489:            public void removeAttribute(String name) {
490:                this .attributes.remove(name);
491:            }
492:
493:            public Enumeration getAttributeNames() {
494:                return new IteratorEnumeration(this .attributes.keySet()
495:                        .iterator());
496:            }
497:
498:            /**
499:             * Get the output stream where to write the generated resource.
500:             * @deprecated Use {@link #getOutputStream(int)} instead.
501:             */
502:            public OutputStream getOutputStream() throws IOException {
503:                Deprecation.logger
504:                        .warn("The method Environment.getOutputStream() "
505:                                + "is deprecated. Use getOutputStream(-1) instead.");
506:                // by default we use the complete buffering output stream
507:                return getOutputStream(-1);
508:            }
509:
510:            /**
511:             * Get the output stream where to write the generated resource.
512:             * The returned stream is buffered by the environment. If the
513:             * buffer size is -1 then the complete output is buffered.
514:             * If the buffer size is 0, no buffering takes place.
515:             *
516:             * <br>This method replaces {@link #getOutputStream()}.
517:             */
518:            public OutputStream getOutputStream(int bufferSize)
519:                    throws IOException {
520:
521:                // This method could be called several times during request processing
522:                // with differing values of bufferSize and should handle this situation
523:                // correctly.
524:
525:                if (bufferSize == -1) {
526:                    if (this .secureOutputStream == null) {
527:                        this .secureOutputStream = new BufferedOutputStream(
528:                                this .outputStream);
529:                    }
530:                    return this .secureOutputStream;
531:                } else if (bufferSize == 0) {
532:                    // Discard secure output stream if it was created before.
533:                    if (this .secureOutputStream != null) {
534:                        this .secureOutputStream = null;
535:                    }
536:                    return this .outputStream;
537:                } else {
538:                    // FIXME Triple buffering, anyone?
539:                    this .outputStream = new java.io.BufferedOutputStream(
540:                            this .outputStream, bufferSize);
541:                    return this .outputStream;
542:                }
543:            }
544:
545:            /**
546:             * Reset the response if possible. This allows error handlers to have
547:             * a higher chance to produce clean output if the pipeline that raised
548:             * the error has already output some data.
549:             *
550:             * @return true if the response was successfully reset
551:             */
552:            public boolean tryResetResponse() throws IOException {
553:                if (this .secureOutputStream != null) {
554:                    this .secureOutputStream.clearBuffer();
555:                    return true;
556:                }
557:                return false;
558:            }
559:
560:            /**
561:             * Commit the response
562:             */
563:            public void commitResponse() throws IOException {
564:                if (this .secureOutputStream != null) {
565:                    this .setContentLength(this .secureOutputStream.getCount());
566:                    this .secureOutputStream.realFlush();
567:                } else if (this .outputStream != null) {
568:                    this .outputStream.flush();
569:                }
570:            }
571:
572:            /**
573:             * Get a <code>Source</code> object.
574:             */
575:            public org.apache.excalibur.source.Source resolveURI(
576:                    final String location) throws MalformedURLException,
577:                    IOException, SourceException {
578:                return this .resolveURI(location, null, null);
579:            }
580:
581:            /**
582:             * Get a <code>Source</code> object.
583:             */
584:            public org.apache.excalibur.source.Source resolveURI(
585:                    final String location, String baseURI, final Map parameters)
586:                    throws MalformedURLException, IOException, SourceException {
587:                if (!this .initializedComponents) {
588:                    this .initComponents();
589:                }
590:                return this .sourceResolver.resolveURI(location, baseURI,
591:                        parameters);
592:            }
593:
594:            /**
595:             * Releases a resolved resource
596:             */
597:            public void release(final org.apache.excalibur.source.Source source) {
598:                if (null != source) {
599:                    this .sourceResolver.release(source);
600:                }
601:            }
602:
603:            /**
604:             * Initialize the components for the environment
605:             * This gets the source resolver and the xmlizer component
606:             */
607:            protected void initComponents() {
608:                this .initializedComponents = true;
609:                try {
610:                    this .manager = CocoonComponentManager
611:                            .getSitemapComponentManager();
612:                    this .sourceResolver = (org.apache.excalibur.source.SourceResolver) this .manager
613:                            .lookup(org.apache.excalibur.source.SourceResolver.ROLE);
614:                    if (this .tempInitContext != null) {
615:                        org.apache.excalibur.source.Source source = null;
616:                        try {
617:                            source = this .sourceResolver
618:                                    .resolveURI(this .tempInitContext);
619:                            this .context = source.getURI();
620:
621:                            if (this .rootContext == null) // hack for EnvironmentWrapper
622:                                this .rootContext = this .context;
623:                        } finally {
624:                            this .sourceResolver.release(source);
625:                        }
626:                        this .tempInitContext = null;
627:                    }
628:                } catch (ComponentException ce) {
629:                    // this should never happen!
630:                    throw new CascadingRuntimeException(
631:                            "Unable to lookup component.", ce);
632:                } catch (IOException ie) {
633:                    throw new CascadingRuntimeException(
634:                            "Unable to resolve URI: " + this .tempInitContext,
635:                            ie);
636:                }
637:            }
638:
639:            /**
640:             * Notify that the processing starts.
641:             */
642:            public void startingProcessing() {
643:                // do nothing here
644:            }
645:
646:            /**
647:             * Notify that the processing is finished
648:             * This can be used to cleanup the environment object
649:             */
650:            public void finishingProcessing() {
651:                if (null != this .manager) {
652:                    this .manager.release(this .sourceResolver);
653:                    this .manager = null;
654:                    this .sourceResolver = null;
655:                }
656:                this .initializedComponents = false;
657:            }
658:
659:            /* (non-Javadoc)
660:             * @see org.apache.cocoon.environment.Environment#isInternRedirect()
661:             */
662:            public boolean isInternalRedirect() {
663:                return false;
664:            }
665:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.