Source Code Cross Referenced for ClassWebResource.java in  » Ajax » zk » org » zkoss » web » util » resource » 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 » Ajax » zk » org.zkoss.web.util.resource 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* ClassWebResource.java
002:
003:        {{IS_NOTE
004:        	Purpose:
005:        		
006:        	Description:
007:        		
008:        	History:
009:        		Tue Sep 20 16:49:45     2005, Created by tomyeh
010:        }}IS_NOTE
011:
012:        Copyright (C) 2005 Potix Corporation. All Rights Reserved.
013:
014:        {{IS_RIGHT
015:        	This program is distributed under GPL Version 2.0 in the hope that
016:        	it will be useful, but WITHOUT ANY WARRANTY.
017:        }}IS_RIGHT
018:         */
019:        package org.zkoss.web.util.resource;
020:
021:        import java.util.Map;
022:        import java.util.HashMap;
023:        import java.net.URL;
024:        import java.io.InputStream;
025:        import java.io.IOException;
026:        import java.io.UnsupportedEncodingException;
027:
028:        import javax.servlet.ServletContext;
029:        import javax.servlet.ServletRequest;
030:        import javax.servlet.ServletResponse;
031:        import javax.servlet.ServletOutputStream;
032:        import javax.servlet.ServletException;
033:        import javax.servlet.RequestDispatcher;
034:        import javax.servlet.http.HttpServletRequest;
035:        import javax.servlet.http.HttpServletResponse;
036:
037:        import org.zkoss.lang.D;
038:        import org.zkoss.io.Files;
039:        import org.zkoss.util.logging.Log;
040:        import org.zkoss.util.media.ContentTypes;
041:        import org.zkoss.util.resource.Locator;
042:        import org.zkoss.util.resource.Locators;
043:
044:        import org.zkoss.web.servlet.Servlets;
045:        import org.zkoss.web.servlet.Charsets;
046:        import org.zkoss.web.servlet.http.Https;
047:        import org.zkoss.web.servlet.http.Encodes;
048:
049:        /**
050:         * Used to access resouces located in class path and under /web.
051:         * It doesn't work alone. Rather, it is a helper for servlet, such as
052:         * ZK's update servlet or {@link ClassWebServlet}.
053:         *
054:         * <p>Typical use:
055:         * <ol>
056:         * <li>Declares a member in the servlet to
057:         * serve the request for the resource located in class path.
058:         * <li>Invoke {@link #getInstance} to init the member when
059:         * Servlet.init() is called.
060:         * <li>Calling {@link #service} when a request is receive.
061:         * </ol>
062:         *
063:         * @author tomyeh
064:         */
065:        public class ClassWebResource {
066:            private static final Log log = Log.lookup(ClassWebResource.class);
067:
068:            private final ServletContext _ctx;
069:            private final String _mappingURI;
070:            private final ClassWebContext _cwc;
071:            /** An array of extensions that have to be compressed (with gzip). */
072:            private String[] _compressExts;
073:            /** Map(String ext, Extendlet). */
074:            private final Map _extlets = new HashMap(5);
075:
076:            /** The prefix of path of web resources ("/web"). */
077:            public static final String PATH_PREFIX = "/web";
078:
079:            /** Returns the URL of the resource of the specified URI by searching
080:             * the class path (with {@link #PATH_PREFIX}).
081:             */
082:            public static URL getResource(String uri) {
083:                return Locators.getDefault().getResource(PATH_PREFIX + uri);
084:            }
085:
086:            /** Returns the resource in a stream of the specified URI by searching
087:             * the class path (with {@link #PATH_PREFIX}).
088:             */
089:            public static InputStream getResourceAsStream(String uri) {
090:                return Locators.getDefault().getResourceAsStream(
091:                        PATH_PREFIX + uri);
092:            }
093:
094:            /** Returns the instance (singlton in the whole app) for
095:             * handling resources located in class path.
096:             */
097:            public static final ClassWebResource getInstance(
098:                    ServletContext ctx, String mappingURI) {
099:                synchronized (ctx) {
100:                    final ClassWebContext cwc = (ClassWebContext) Servlets
101:                            .getExtendletContext(ctx, ".");
102:                    if (cwc != null)
103:                        return cwc.getClassWebResource();
104:
105:                    final ClassWebResource cwr = new ClassWebResource(ctx,
106:                            mappingURI);
107:                    Servlets.addExtendletContext(ctx, ".", cwr._cwc);
108:                    return cwr;
109:                }
110:            }
111:
112:            /** Constructor. */
113:            private ClassWebResource(ServletContext ctx, String mappingURI) {
114:                if (!mappingURI.startsWith("/") || mappingURI.endsWith("/"))
115:                    throw new IllegalArgumentException(
116:                            "mappingURI must start with /, but not ends with /");
117:                if (ctx == null)
118:                    throw new IllegalArgumentException("null ctx");
119:
120:                _ctx = ctx;
121:                _mappingURI = mappingURI;
122:                _cwc = new ClassWebContext();
123:                addExtendlet("dsp", new DspExtendlet());
124:            }
125:
126:            /** Process the request by retrieving the path from the path info.
127:             * It invokes {@link Https#getThisPathInfo} to retrieve the path info,
128:             * and then invoke {@link #service(HttpServletRequest,HttpServletResponse,String)}.
129:             *
130:             * <p>If the path info is not found, nothing is generated.
131:             *
132:             * @since 2.4.1
133:             */
134:            public void service(HttpServletRequest request,
135:                    HttpServletResponse response) throws ServletException,
136:                    IOException {
137:                final String pi = Https.getThisPathInfo(request);
138:                //		if (D.ON && log.debugable()) log.debug("Path info: "+pi);
139:                if (pi != null)
140:                    service(request, response, pi.substring(PATH_PREFIX
141:                            .length()));
142:            }
143:
144:            /** Process the request with the specified path.
145:             *
146:             * @param path the path related to the class path
147:             * @since 3.0.0
148:             */
149:            public void service(HttpServletRequest request,
150:                    HttpServletResponse response, String path)
151:                    throws ServletException, IOException {
152:                final Object old = Charsets.setup(request, response, "UTF-8");
153:                try {
154:                    web(request, response, path);
155:                } finally {
156:                    Charsets.cleanup(request, old);
157:                }
158:            }
159:
160:            /** Returns the Extendlet (aka., resource processor) of the
161:             * specified extension, or null if not associated yet.
162:             *
163:             * @param ext the extension, e.g, "js" and "css".
164:             * @return the Extendlet (aka., resource processor),
165:             * or null if not associated yet.
166:             * @since 2.4.1
167:             */
168:            public Extendlet getExtendlet(String ext) {
169:                if (ext == null)
170:                    return null;
171:
172:                ext = ext.toLowerCase();
173:                synchronized (_extlets) {
174:                    return (Extendlet) _extlets.get(ext);
175:                }
176:            }
177:
178:            /** Adds an Extendlet (aka., resource processor) to process
179:             * the resource of the specified extension.
180:             *
181:             * @param ext the extension, e.g, "js" and "css".
182:             * @param extlet the Extendlet (aka., resouce processor) to add
183:             * @return the previous Extendlet, or null if not associated before.
184:             * @since 2.4.1
185:             */
186:            public Extendlet addExtendlet(String ext, Extendlet extlet) {
187:                if (ext == null || extlet == null)
188:                    throw new IllegalArgumentException("null");
189:
190:                extlet.init(new ExtendletConfig() {
191:                    public ExtendletContext getExtendletContext() {
192:                        return _cwc;
193:                    }
194:                });
195:
196:                ext = ext.toLowerCase();
197:                synchronized (_extlets) {
198:                    return (Extendlet) _extlets.put(ext, extlet);
199:                }
200:            }
201:
202:            /** Removes the Extendlet (aka., resource processor)
203:             * for the specified extension.
204:             *
205:             * @param ext the extension, e.g, "js" and "css".
206:             * @return the previous Extendlet, or null if no Extendlet
207:             * was associated with the specified extension.
208:             * @since 2.4.1
209:             */
210:            public Extendlet removeExtendlet(String ext) {
211:                if (ext == null)
212:                    return null;
213:
214:                ext = ext.toLowerCase();
215:                synchronized (_extlets) {
216:                    return (Extendlet) _extlets.remove(ext);
217:                }
218:            }
219:
220:            /** Sets the extension that shall be compressed if the browser
221:             * supports the compression encoding (accept-encoding).
222:             *
223:             * <p>Default: null (no compression at all).
224:             *
225:             * @param exts an array of extensions, e.g., {"js", "css"}.
226:             * If null or zero-length, it means no compression at all.
227:             *@since 2.4.1
228:             */
229:            public void setCompress(String[] exts) {
230:                _compressExts = exts != null && exts.length > 0 ? exts : null;
231:            }
232:
233:            /**Returns  the extension that shall be compressed if the browser
234:             * supports the compression encoding (accept-encoding).
235:             *
236:             * <p>Default: null (no compression at all).
237:             *@since 2.4.1
238:             */
239:            public String[] getCompress() {
240:                return _compressExts;
241:            }
242:
243:            //-- Work with ClassWebContext --//
244:            /** Works with {@link ClassWebContext} to
245:             * load resources from class path (thru this servlet).
246:             */
247:            private void web(HttpServletRequest request,
248:                    HttpServletResponse response, String pi)
249:                    throws ServletException, IOException {
250:                //A trick used to enforce browser to load new version JavaScript
251:                //How it work: client engine prefix URI with /_zver123, where
252:                //123 is the build version that changes once reload is required
253:                //Then, the server eliminate such prefix before locating resource
254:                final String ZVER = "/_zver";
255:                if (pi.startsWith(ZVER)) {
256:                    final int j = pi.indexOf('/', ZVER.length());
257:                    if (j >= 0)
258:                        pi = pi.substring(j);
259:                    else
260:                        log.warning("Unknown path info: " + pi);
261:                }
262:
263:                //Notify the browser by calling back the code specified with /_zcb
264:                String jsextra = null;
265:                final String ZCB = "/_zcb"; //denote callback is required
266:                if (pi.startsWith(ZCB)) {
267:                    final int j = pi.indexOf('/', ZCB.length());
268:                    if (j >= 0) {
269:                        jsextra = pi.substring(ZCB.length(), j);
270:                        pi = pi.substring(j);
271:                    } else {
272:                        jsextra = pi.substring(ZCB.length());
273:                        log.warning("Unknown path info: " + pi);
274:                    }
275:
276:                    final int len = jsextra.length();
277:                    if (len == 0)
278:                        jsextra = null;
279:                    else {
280:                        final char cc = jsextra.charAt(len - 1);
281:                        if (cc != ';') {
282:                            if (cc != ')')
283:                                jsextra += "()";
284:                            jsextra += ';';
285:                        }
286:                    }
287:                }
288:
289:                final String ext = Servlets.getExtension(pi);
290:                if (ext != null) {
291:                    //Invoke the resource processor (Extendlet)
292:                    final Extendlet extlet = getExtendlet(ext);
293:                    if (extlet != null) {
294:                        extlet.service(request, response, pi, jsextra);
295:                        return;
296:                    }
297:
298:                    if (!Servlets.isIncluded(request)) {
299:                        final String ctype = ContentTypes.getContentType(ext);
300:                        if (ctype != null)
301:                            response.setContentType(ctype);
302:                        //				if (D.ON && log.debugable()) log.debug("Content type: "+ctype+" for "+pi);
303:                    }
304:                }
305:
306:                byte[] extra = jsextra != null ? jsextra.getBytes("UTF-8")
307:                        : null;
308:                pi = Servlets.locate(_ctx, request, pi, _cwc.getLocator());
309:                final InputStream is = getResourceAsStream(pi);
310:                byte[] data;
311:                if (is == null) {
312:                    if ("js".equals(ext)) {
313:                        //Don't sendError. Reason: 1) IE waits and no onerror fired
314:                        //2) better to debug (user will tell us what went wrong)
315:                        data = ("(zk.error?zk.error:alert)('" + pi + " not found');")
316:                                .getBytes();
317:                        //FUTURE: zweb shall not depend on zk
318:                    } else {
319:                        if (Servlets.isIncluded(request))
320:                            log.error("Resource not found: " + pi);
321:                        response.sendError(response.SC_NOT_FOUND, pi);
322:                        return;
323:                    }
324:                } else {
325:                    //Note: don't compress images
326:                    data = shallCompress(request, ext) ? Https.gzip(request,
327:                            response, is, extra) : null;
328:                    if (data != null)
329:                        extra = null; //extra is compressed and output
330:                    else
331:                        data = Files.readAll(is);
332:                    //since what is embedded in the jar is not big, so load completely
333:                }
334:
335:                int len = data.length;
336:                if (extra != null)
337:                    len += extra.length;
338:                response.setContentLength(len);
339:
340:                final ServletOutputStream out = response.getOutputStream();
341:                out.write(data);
342:                if (extra != null)
343:                    out.write(extra);
344:                out.flush();
345:            }
346:
347:            private boolean shallCompress(ServletRequest request, String ext) {
348:                if (ext != null && _compressExts != null
349:                        && !Servlets.isIncluded(request))
350:                    for (int j = 0; j < _compressExts.length; ++j)
351:                        if (ext.equals(_compressExts[j]))
352:                            return true;
353:                return false;
354:            }
355:
356:            /**
357:             * An implementation of ExtendletContext to load resources from
358:             * the class path rooted at /web.
359:             */
360:            private class ClassWebContext implements  ExtendletContext {
361:                private final Locator _locator = new Locator() {
362:                    public String getDirectory() {
363:                        return null;
364:                    }
365:
366:                    public URL getResource(String name) {
367:                        return ClassWebResource.getResource(name);
368:                    }
369:
370:                    public InputStream getResourceAsStream(String name) {
371:                        return ClassWebResource.getResourceAsStream(name);
372:                    }
373:                };
374:
375:                /** Returns the associated class web resource. */
376:                public ClassWebResource getClassWebResource() {
377:                    return ClassWebResource.this ;
378:                }
379:
380:                //-- ExtendletContext --//
381:                public ServletContext getServletContext() {
382:                    return _ctx;
383:                }
384:
385:                public Locator getLocator() {
386:                    return _locator;
387:                }
388:
389:                public boolean shallCompress(ServletRequest request, String ext) {
390:                    return ClassWebResource.this .shallCompress(request, ext);
391:                }
392:
393:                public String encodeURL(ServletRequest request,
394:                        ServletResponse response, String uri)
395:                        throws ServletException, UnsupportedEncodingException {
396:                    uri = Servlets.locate(_ctx, request, uri, getLocator()); //resolves "*"
397:                    uri = _mappingURI + PATH_PREFIX + uri; //prefix with mapping
398:
399:                    //prefix context path
400:                    if (request instanceof  HttpServletRequest) {
401:                        String ctxpath = ((HttpServletRequest) request)
402:                                .getContextPath();
403:                        final int ctxlen = ctxpath.length();
404:                        if (ctxlen > 0) {
405:                            final char cc = ctxpath.charAt(0);
406:                            if (cc != '/')
407:                                ctxpath = '/' + ctxpath;
408:                            //Work around a bug for Pluto's RenderRequest (1.0.1)
409:                            else if (ctxlen == 1)
410:                                ctxpath = ""; // "/" =>  ""
411:                            //Work around liferay's issue: Upload 1627928 (not verified)
412:                        }
413:                        uri = ctxpath + uri;
414:                    }
415:
416:                    int j = uri.indexOf('?');
417:                    if (j < 0) {
418:                        uri = Encodes.encodeURI(uri);
419:                    } else {
420:                        uri = Encodes.encodeURI(uri.substring(0, j))
421:                                + uri.substring(j);
422:                    }
423:                    //encode
424:                    if (response instanceof  HttpServletResponse)
425:                        uri = ((HttpServletResponse) response).encodeURL(uri);
426:                    return uri;
427:                }
428:
429:                public String encodeRedirectURL(HttpServletRequest request,
430:                        HttpServletResponse response, String uri, Map params,
431:                        int mode) {
432:                    return Https.encodeRedirectURL(_ctx, request, response,
433:                            _mappingURI + PATH_PREFIX + uri, params, mode);
434:                }
435:
436:                public RequestDispatcher getRequestDispatcher(String uri) {
437:                    //			if (D.ON && log.debugable()) log.debug("getRequestDispatcher: "+uri);
438:                    return _ctx.getRequestDispatcher(_mappingURI + PATH_PREFIX
439:                            + uri);
440:                }
441:
442:                public URL getResource(String uri) {
443:                    return ClassWebResource.getResource(uri);
444:                }
445:
446:                public InputStream getResourceAsStream(String uri) {
447:                    return ClassWebResource.getResourceAsStream(uri);
448:                }
449:            }
450:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.