001: /* PageDefinitions.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Tue May 31 12:34:43 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.zk.ui.metainfo;
020:
021: import java.io.File;
022: import java.io.Reader;
023: import java.io.StringReader;
024: import java.io.IOException;
025: import java.net.URL;
026: import javax.servlet.ServletContext;
027:
028: import org.zkoss.lang.D;
029: import org.zkoss.util.resource.Locator;
030: import org.zkoss.util.resource.ResourceCache;
031: import org.zkoss.idom.Document;
032: import org.zkoss.web.util.resource.ServletContextLocator;
033: import org.zkoss.web.util.resource.ResourceCaches;
034: import org.zkoss.web.util.resource.ResourceLoader;
035:
036: import org.zkoss.zk.ui.WebApp;
037: import org.zkoss.zk.ui.UiException;
038: import org.zkoss.zk.ui.Execution;
039: import org.zkoss.zk.ui.Executions;
040: import org.zkoss.zk.ui.metainfo.Parser;
041:
042: /**
043: * Utilities to retrieve page definitions.
044: *
045: * @author tomyeh
046: */
047: public class PageDefinitions {
048: private static final String ATTR_PAGE_CACHE = "org.zkoss.zk.ui.PageCache";
049:
050: /** Returns the page definition of the specified raw content; never null.
051: *
052: * <p>This is the lowest method that other getPageDefinitionDirectly depends.
053: *
054: * <p>Dependency: Execution.createComponentsDirectly -& Execution.getPageDefinitionDirectly
055: * -& UiFactory.getPageDefiitionDirectly -& PageDefintions.getPageDefinitionDirectly
056: *
057: * @param locator the locator used to locate taglib and other resources.
058: * If null, wapp is assumed ({@link WebApp} is also assumed).
059: * @param extension the default extension if the content doesn't specify
060: * an language. In other words, if
061: * the content doesn't specify an language, {@link LanguageDefinition#getByExtension}
062: * is called.
063: * If extension is null and the content doesn't specify a language,
064: * the language called "xul/html" is assumed.
065: * @exception UiException if failed to parse
066: */
067: public static final PageDefinition getPageDefinitionDirectly(
068: WebApp wapp, Locator locator, String content,
069: String extension) {
070: try {
071: return getPageDefinitionDirectly(wapp, locator,
072: new StringReader(content), extension);
073: } catch (IOException ex) {
074: throw UiException.Aide.wrap(ex);
075: }
076: }
077:
078: /** Returns the page definition of the raw content from the specified
079: * reader; never null.
080: *
081: * @param locator the locator used to locate taglib and other resources.
082: * If null, wapp is assumed ({@link WebApp} is also assumed).
083: * @param extension the default extension if the content doesn't specify
084: * an language. In other words, if
085: * the content doesn't specify an language, {@link LanguageDefinition#getByExtension}
086: * is called.
087: * If extension is null and the content doesn't specify a language,
088: * the language called "xul/html" is assumed.
089: * @exception UiException if failed to parse
090: */
091: public static final PageDefinition getPageDefinitionDirectly(
092: WebApp wapp, Locator locator, Reader reader,
093: String extension) throws IOException {
094: try {
095: return new Parser(wapp, locator).parse(reader, extension);
096: } catch (IOException ex) {
097: throw (IOException) ex;
098: } catch (Exception ex) {
099: throw UiException.Aide.wrap(ex);
100: }
101: }
102:
103: /** Returns the page definition of the specified raw content in DOM;
104: * never null.
105: *
106: * @param locator the locator used to locate taglib and other resources.
107: * If null, wapp is assumed ({@link WebApp} is also assumed).
108: * @param extension the default extension if the content doesn't specify
109: * an language. In other words, if
110: * the content doesn't specify an language, {@link LanguageDefinition#getByExtension}
111: * is called.
112: * If extension is null and the content doesn't specify a language,
113: * the language called "xul/html" is assumed.
114: * @exception UiException if failed to parse
115: */
116: public static final PageDefinition getPageDefinitionDirectly(
117: WebApp wapp, Locator locator, Document doc, String extension) {
118: try {
119: return new Parser(wapp, locator).parse(doc, extension);
120: } catch (Exception ex) {
121: throw UiException.Aide.wrap(ex);
122: }
123: }
124:
125: /** Returns the page definition of the specified path, or null if not
126: * found or failed to parse.
127: *
128: * <p>This is the lowest method that other getPageDefinition depends.
129: *
130: * <p>Dependency: Execution.createComponents -& Execution.getPageDefinition
131: * -& UiFactory.getPageDefiition -& PageDefintions.getPageDefinition
132: *
133: * @param locator the locator used to locate taglib and other resources.
134: * If null, wapp is assumed ({@link WebApp} is also assumed).
135: */
136: public static final PageDefinition getPageDefinition(WebApp wapp,
137: Locator locator, String path) {
138: wapp.getConfiguration().invokeURIInterceptors(path);
139: //give the security a chance to reject
140:
141: final Object ctx = wapp.getNativeContext();
142: if (ctx instanceof ServletContext)
143: return (PageDefinition) ResourceCaches.get(getCache(wapp),
144: (ServletContext) ctx, path, locator);
145: throw new UnsupportedOperationException("Unknown context: "
146: + ctx);
147: }
148:
149: /** Returns the locator for the specified context.
150: *
151: * @param path the original path, or null if not available.
152: * The original path is used to resolve a relative path.
153: * If not specified, {@link org.zkoss.zk.ui.Desktop#getCurrentDirectory}
154: * is used.
155: */
156: public static final Locator getLocator(WebApp wapp, String path) {
157: if (wapp == null)
158: throw new IllegalArgumentException("null");
159:
160: if (path != null && path.length() > 0 && path.charAt(0) == '/') {
161: final int j = path.lastIndexOf('/');
162: path = j > 0 ? path.substring(0, j + 1) : "/";
163: } else {
164: final Execution exec = Executions.getCurrent();
165: if (exec != null)
166: path = exec.getDesktop().getCurrentDirectory();
167: }
168: final Object ctx = wapp.getNativeContext();
169: if (ctx instanceof ServletContext)
170: return new ServletContextLocator((ServletContext) ctx, path);
171: throw new UnsupportedOperationException("Unknown context: "
172: + ctx);
173: }
174:
175: private static final ResourceCache getCache(WebApp wapp) {
176: ResourceCache cache = (ResourceCache) wapp
177: .getAttribute(ATTR_PAGE_CACHE);
178: if (cache == null) {
179: synchronized (PageDefinitions.class) {
180: cache = (ResourceCache) wapp
181: .getAttribute(ATTR_PAGE_CACHE);
182: if (cache == null) {
183: cache = new ResourceCache(new MyLoader(wapp), 167);
184: cache.setMaxSize(1024);
185: cache.setLifetime(60 * 60000); //1hr
186: wapp.setAttribute(ATTR_PAGE_CACHE, cache);
187: }
188: }
189: }
190: return cache;
191: }
192:
193: private static class MyLoader extends ResourceLoader {
194: private final WebApp _wapp;
195:
196: private MyLoader(WebApp wapp) {
197: _wapp = wapp;
198: }
199:
200: //-- super --//
201: protected Object parse(String path, File file, Object extra)
202: throws Exception {
203: final Locator locator = extra != null ? (Locator) extra
204: : getLocator(_wapp, path);
205: return new Parser(_wapp, locator).parse(file, path);
206: }
207:
208: protected Object parse(String path, URL url, Object extra)
209: throws Exception {
210: final Locator locator = extra != null ? (Locator) extra
211: : getLocator(_wapp, path);
212: return new Parser(_wapp, locator).parse(url, path);
213: }
214: }
215: }
|