KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > environment > AbstractEnvironment


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.environment;
17
18 import java.io.File JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.net.MalformedURLException JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import org.apache.avalon.framework.CascadingRuntimeException;
28 import org.apache.avalon.framework.component.ComponentException;
29 import org.apache.avalon.framework.component.ComponentManager;
30 import org.apache.avalon.framework.logger.AbstractLogEnabled;
31 import org.apache.cocoon.Constants;
32 import org.apache.cocoon.ProcessingException;
33 import org.apache.cocoon.components.CocoonComponentManager;
34 import org.apache.cocoon.components.source.SourceUtil;
35 import org.apache.cocoon.util.BufferedOutputStream;
36 import org.apache.cocoon.util.ClassUtils;
37 import org.apache.cocoon.util.Deprecation;
38 import org.apache.commons.collections.iterators.IteratorEnumeration;
39 import org.apache.excalibur.source.SourceException;
40 import org.xml.sax.SAXException JavaDoc;
41
42 /**
43  * Base class for any environment
44  *
45  * @author <a HREF="mailto:bluetkemeier@s-und-n.de">Bj&ouml;rn L&uuml;tkemeier</a>
46  * @author <a HREF="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
47  * @author <a HREF="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
48  * @version CVS $Id: AbstractEnvironment.java 226272 2005-07-28 22:43:30Z vgritsenko $
49  */

50 public abstract class AbstractEnvironment extends AbstractLogEnabled implements Environment {
51
52     /** The current uri in progress */
53     protected String JavaDoc uris;
54
55     /** The current prefix to strip off from the request uri */
56     protected StringBuffer JavaDoc prefix = new StringBuffer JavaDoc();
57
58     /** The View requested */
59     protected String JavaDoc view;
60
61     /** The Action requested */
62     protected String JavaDoc action;
63
64      /** The Context path */
65     protected String JavaDoc context;
66
67     /** The context path stored temporarily between constructor and initComponents */
68     private String JavaDoc tempInitContext;
69
70     /** The root context path */
71     protected String JavaDoc rootContext;
72
73     /** The servlet object model */
74     protected HashMap JavaDoc objectModel;
75
76     /** The real source resolver */
77     protected org.apache.excalibur.source.SourceResolver sourceResolver;
78
79     /** The component manager */
80     protected ComponentManager manager;
81
82     /** The attributes */
83     private Map JavaDoc attributes = new HashMap JavaDoc();
84
85     /** The secure Output Stream */
86     protected BufferedOutputStream secureOutputStream;
87
88     /** The real output stream */
89     protected OutputStream JavaDoc outputStream;
90
91     /** The AvalonToCocoonSourceWrapper (this is for the deprecated support) */
92     static protected Method JavaDoc avalonToCocoonSourceWrapper;
93
94     /** Do we have our components ? */
95     protected boolean initializedComponents = false;
96
97     /**
98      * Constructs the abstract environment
99      */

100     public AbstractEnvironment(String JavaDoc uri, String JavaDoc view, File JavaDoc file)
101     throws MalformedURLException JavaDoc {
102         this(uri, view, file, null);
103     }
104
105     /**
106      * Constructs the abstract environment
107      */

108     public AbstractEnvironment(String JavaDoc uri, String JavaDoc view, File JavaDoc file, String JavaDoc action)
109     throws MalformedURLException JavaDoc {
110         this(uri, view, file.toURL().toExternalForm(), action);
111     }
112
113     /**
114      * Constructs the abstract environment
115      */

116     public AbstractEnvironment(String JavaDoc uri, String JavaDoc view, String JavaDoc context, String JavaDoc action)
117     throws MalformedURLException JavaDoc {
118         this.uris = uri;
119         this.view = view;
120         this.tempInitContext = context;
121         this.action = action;
122         this.objectModel = new HashMap JavaDoc();
123     }
124
125     /**
126      * Allow implementations to set view later than in super() constructor.
127      * View can be set only once, and should be set in implementation's constructor.
128      */

129     protected void setView(String JavaDoc view) {
130         if (this.view != null) {
131             throw new IllegalStateException JavaDoc("View was already set on this environment");
132         }
133         this.view = view;
134     }
135
136     /**
137      * Allow implementations to set action later than in super() constructor
138      * Action can be set only once, and should be set in implementation's constructor.
139      */

140     protected void setAction(String JavaDoc action) {
141         if (this.action != null) {
142             throw new IllegalStateException JavaDoc("Action was already set on this environment");
143         }
144         this.action = action;
145     }
146
147     /**
148      * Helper method to extract the view name from the request.
149      */

150     protected static String JavaDoc extractView(Request request) {
151         return request.getParameter(Constants.VIEW_PARAM);
152     }
153
154     /**
155      * Helper method to extract the action name from the request.
156      */

157      protected static String JavaDoc extractAction(Request req) {
158          String JavaDoc action = req.getParameter(Constants.ACTION_PARAM);
159          if (action != null) {
160              /* TC: still support the deprecated syntax */
161              return action;
162          } else {
163              for(Enumeration JavaDoc e = req.getParameterNames(); e.hasMoreElements(); ) {
164                  String JavaDoc name = (String JavaDoc)e.nextElement();
165                  if (name.startsWith(Constants.ACTION_PARAM_PREFIX)) {
166                      if (name.endsWith(".x") || name.endsWith(".y")) {
167                          return name.substring(Constants.ACTION_PARAM_PREFIX.length(),name.length()-2);
168                      } else {
169                          return name.substring(Constants.ACTION_PARAM_PREFIX.length());
170                      }
171                  }
172              }
173              return null;
174          }
175      }
176
177     // Sitemap methods
178

179     /**
180      * Returns the uri in progress. The prefix is stripped off
181      */

182     public String JavaDoc getURI() {
183         return this.uris;
184     }
185
186     /**
187      * Get the Root Context
188      */

189     public String JavaDoc getRootContext() {
190         if ( !this.initializedComponents) {
191             this.initComponents();
192         }
193         return this.rootContext;
194     }
195
196     /**
197      * Get the current Context
198      */

199     public String JavaDoc getContext() {
200         if (!this.initializedComponents) {
201             this.initComponents();
202         }
203         return this.context;
204     }
205
206     /**
207      * Get the prefix of the URI in progress
208      */

209     public String JavaDoc getURIPrefix() {
210         return this.prefix.toString();
211     }
212
213     /**
214      * Set the prefix of the URI in progress
215      */

216     protected void setURIPrefix(String JavaDoc prefix) {
217         if (getLogger().isDebugEnabled()) {
218             getLogger().debug("Set the URI Prefix (OLD=" + getURIPrefix() + ", NEW=" + prefix + ")");
219         }
220         this.prefix = new StringBuffer JavaDoc(prefix);
221     }
222
223     /**
224      * Set the context.
225      */

226     protected void setContext(String JavaDoc context) {
227         this.context = context;
228     }
229
230     /**
231      * Set the context. This is similar to changeContext()
232      * except that it is absolute.
233      */

234     public void setContext(String JavaDoc prefix, String JavaDoc uri, String JavaDoc context) {
235         this.setContext(context);
236         this.setURIPrefix(prefix == null ? "" : prefix);
237         this.uris = uri;
238         if (getLogger().isDebugEnabled()) {
239             getLogger().debug("Reset context to " + this.context);
240         }
241     }
242
243     /**
244      * Adds an prefix to the overall stripped off prefix from the request uri
245      */

246     public void changeContext(String JavaDoc newPrefix, String JavaDoc newContext)
247     throws IOException JavaDoc {
248         if (!this.initializedComponents) {
249             this.initComponents();
250         }
251
252         if (getLogger().isDebugEnabled()) {
253             getLogger().debug("Changing Cocoon context");
254             getLogger().debug(" from context(" + this.context + ") and prefix(" + this.prefix + ")");
255             getLogger().debug(" to context(" + newContext + ") and prefix(" + newPrefix + ")");
256             getLogger().debug(" at URI " + this.uris);
257         }
258
259         int l = newPrefix.length();
260         if (l >= 1) {
261             if (!this.uris.startsWith(newPrefix)) {
262                 String JavaDoc message = "The current URI (" + this.uris +
263                                  ") doesn't start with given prefix (" + newPrefix + ")";
264                 getLogger().error(message);
265                 throw new RuntimeException JavaDoc(message);
266             }
267             this.prefix.append(newPrefix);
268             this.uris = this.uris.substring(l);
269
270             // check for a slash at the beginning to avoid problems with subsitemaps
271
if (this.uris.startsWith("/")) {
272                 this.uris = this.uris.substring(1);
273                 this.prefix.append('/');
274             }
275         }
276
277         if (this.context.startsWith("zip:")) {
278             // if the resource is zipped into a war file (e.g. Weblogic temp deployment)
279
// FIXME (VG): Is this still required? Better to unify both cases.
280
if (getLogger().isDebugEnabled()) {
281                 getLogger().debug("Base context is zip: " + this.context);
282             }
283
284             org.apache.excalibur.source.Source source = null;
285             try {
286                 source = this.sourceResolver.resolveURI(this.context + newContext);
287                 this.context = source.getURI();
288             } finally {
289                 this.sourceResolver.release(source);
290             }
291         } else if (newContext.length() > 0){
292             String JavaDoc sContext;
293             // if we got a absolute context or one with a protocol resolve it
294
if (newContext.charAt(0) == '/') {
295                 // context starts with the '/' - absolute file URL
296
sContext = "file:" + newContext;
297             } else if (newContext.indexOf(':') > 1) {
298                 // context have ':' - absolute URL
299
sContext = newContext;
300             } else {
301                 // context is relative to old one
302
sContext = this.context + '/' + newContext;
303             }
304
305             // Cut the file name part from context (if present)
306
int i = sContext.lastIndexOf('/');
307             if (i != -1 && i + 1 < sContext.length()) {
308                 sContext = sContext.substring(0, i + 1);
309             }
310
311             org.apache.excalibur.source.Source source = null;
312             try {
313                 source = this.sourceResolver.resolveURI(sContext);
314                 this.context = source.getURI();
315             } finally {
316                 this.sourceResolver.release(source);
317             }
318         }
319
320         if (getLogger().isDebugEnabled()) {
321             getLogger().debug("New context is " + this.context);
322         }
323     }
324
325     /**
326      * Redirect the client to a new URL
327      */

328     public abstract void redirect(boolean sessionmode, String JavaDoc newURL) throws IOException JavaDoc;
329
330     public void globalRedirect(boolean sessionmode, String JavaDoc newURL) throws IOException JavaDoc {
331         redirect(sessionmode, newURL);
332     }
333
334     // Request methods
335

336     /**
337      * Returns the request view
338      */

339     public String JavaDoc getView() {
340         return this.view;
341     }
342
343     /**
344      * Returns the request action
345      */

346     public String JavaDoc getAction() {
347         return this.action;
348     }
349
350     // Response methods
351

352     /**
353      * Set a status code
354      */

355     public void setStatus(int statusCode) {
356     }
357
358     // Object model method
359

360     /**
361      * Returns a Map containing environment specific objects
362      */

363     public Map JavaDoc getObjectModel() {
364         return this.objectModel;
365     }
366
367     /**
368      * Resolve an entity.
369      * @deprecated Use the resolveURI methods instead
370      */

371     public Source resolve(String JavaDoc systemId)
372     throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
373         Deprecation.logger.warn("The method SourceResolver.resolve(String) is "
374                               + "deprecated. Use resolveURI(String) instead.");
375         if (!this.initializedComponents) {
376             initComponents();
377         }
378
379         if (getLogger().isDebugEnabled()) {
380             getLogger().debug("Resolving '" + systemId + "' in context '" + this.context + "'");
381         }
382
383         if (systemId == null) {
384             throw new SAXException JavaDoc("Invalid System ID");
385         }
386
387         // get the wrapper class - we don't want to import the wrapper directly
388
// to avoid a direct dependency from the core to the deprecation package
389
Class JavaDoc clazz;
390         try {
391             clazz = ClassUtils.loadClass("org.apache.cocoon.components.source.impl.AvalonToCocoonSourceInvocationHandler");
392         } catch (Exception JavaDoc e) {
393             throw new ProcessingException("The deprecated resolve() method of the environment was called."
394                                           +"Please either update your code to use the new resolveURI() method or"
395                                           +" install the deprecation support.", e);
396         }
397
398         if (null == avalonToCocoonSourceWrapper) {
399             synchronized (getClass()) {
400                 try {
401                     avalonToCocoonSourceWrapper = clazz.getDeclaredMethod("createProxy",
402                            new Class JavaDoc[] {ClassUtils.loadClass("org.apache.excalibur.source.Source"),
403                                         ClassUtils.loadClass("org.apache.excalibur.source.SourceResolver"),
404                                         ClassUtils.loadClass(Environment.class.getName()),
405                                         ClassUtils.loadClass(ComponentManager.class.getName())});
406                 } catch (Exception JavaDoc e) {
407                     throw new ProcessingException("The deprecated resolve() method of the environment was called."
408                                                   +"Please either update your code to use the new resolveURI() method or"
409                                                   +" install the deprecation support.", e);
410                 }
411             }
412         }
413
414         try {
415             org.apache.excalibur.source.Source source = resolveURI(systemId);
416             Source wrappedSource = (Source)avalonToCocoonSourceWrapper.invoke(
417                     clazz,
418                     new Object JavaDoc[] {source, this.sourceResolver, this, this.manager});
419             return wrappedSource;
420         } catch (SourceException se) {
421             throw SourceUtil.handle(se);
422         } catch (Exception JavaDoc e) {
423             throw new ProcessingException("Unable to create source wrapper.", e);
424         }
425     }
426
427     /**
428      * Check if the response has been modified since the same
429      * "resource" was requested.
430      * The caller has to test if it is really the same "resource"
431      * which is requested.
432      * @return true if the response is modified or if the
433      * environment is not able to test it
434      */

435     public boolean isResponseModified(long lastModified) {
436         return true; // always modified
437
}
438
439     /**
440      * Mark the response as not modified.
441      */

442     public void setResponseIsNotModified() {
443         // does nothing
444
}
445
446     public Object JavaDoc getAttribute(String JavaDoc name) {
447         return this.attributes.get(name);
448     }
449
450     public void setAttribute(String JavaDoc name, Object JavaDoc value) {
451         this.attributes.put(name, value);
452     }
453
454     protected boolean hasAttribute(String JavaDoc name) {
455         return this.attributes.containsKey(name);
456     }
457
458     public void removeAttribute(String JavaDoc name) {
459         this.attributes.remove(name);
460     }
461
462     public Enumeration JavaDoc getAttributeNames() {
463         return new IteratorEnumeration(this.attributes.keySet().iterator());
464     }
465
466     /**
467      * Get the output stream where to write the generated resource.
468      * @deprecated Use {@link #getOutputStream(int)} instead.
469      */

470     public OutputStream JavaDoc getOutputStream() throws IOException JavaDoc {
471         Deprecation.logger.warn("The method Environment.getOutputStream() " +
472                               "is deprecated. Use getOutputStream(-1) instead.");
473         // by default we use the complete buffering output stream
474
return this.getOutputStream(-1);
475     }
476
477     /**
478      * Get the output stream where to write the generated resource.
479      * The returned stream is buffered by the environment. If the
480      * buffer size is -1 then the complete output is buffered.
481      * If the buffer size is 0, no buffering takes place.
482      *
483      * <br>This method replaces {@link #getOutputStream()}.
484      */

485     public OutputStream JavaDoc getOutputStream(int bufferSize)
486     throws IOException JavaDoc {
487
488         // This method could be called several times during request processing
489
// with differing values of bufferSize and should handle this situation
490
// correctly.
491

492         if (bufferSize == -1) {
493             if (this.secureOutputStream == null) {
494                 this.secureOutputStream = new BufferedOutputStream(this.outputStream);
495             }
496             return this.secureOutputStream;
497         } else if (bufferSize == 0) {
498             // Discard secure output stream if it was created before.
499
if (this.secureOutputStream != null) {
500                 this.secureOutputStream = null;
501             }
502             return this.outputStream;
503         } else {
504             // FIXME Triple buffering, anyone?
505
this.outputStream = new java.io.BufferedOutputStream JavaDoc(this.outputStream, bufferSize);
506             return this.outputStream;
507         }
508     }
509
510     /**
511      * Reset the response if possible. This allows error handlers to have
512      * a higher chance to produce clean output if the pipeline that raised
513      * the error has already output some data.
514      *
515      * @return true if the response was successfully reset
516     */

517     public boolean tryResetResponse()
518     throws IOException JavaDoc {
519         if (this.secureOutputStream != null) {
520             this.secureOutputStream.clearBuffer();
521             return true;
522         }
523         return false;
524     }
525
526     /**
527      * Commit the response
528      */

529     public void commitResponse()
530     throws IOException JavaDoc {
531         if (this.secureOutputStream != null) {
532             this.setContentLength(this.secureOutputStream.getCount());
533             this.secureOutputStream.realFlush();
534         } else if (this.outputStream != null) {
535             this.outputStream.flush();
536         }
537     }
538
539     /**
540      * Get a <code>Source</code> object.
541      */

542     public org.apache.excalibur.source.Source resolveURI(final String JavaDoc location)
543     throws MalformedURLException JavaDoc, IOException JavaDoc, SourceException {
544         return this.resolveURI(location, null, null);
545     }
546
547     /**
548      * Get a <code>Source</code> object.
549      */

550     public org.apache.excalibur.source.Source resolveURI(final String JavaDoc location,
551                                                          String JavaDoc baseURI,
552                                                          final Map JavaDoc parameters)
553     throws MalformedURLException JavaDoc, IOException JavaDoc, SourceException {
554         if (!this.initializedComponents) {
555             this.initComponents();
556         }
557         return this.sourceResolver.resolveURI(location, baseURI, parameters);
558     }
559
560     /**
561      * Releases a resolved resource
562      */

563     public void release(final org.apache.excalibur.source.Source source) {
564         if (null != source) {
565             this.sourceResolver.release(source);
566         }
567     }
568
569     /**
570      * Initialize the components for the environment
571      * This gets the source resolver and the xmlizer component
572      */

573     protected void initComponents() {
574         this.initializedComponents = true;
575         try {
576             this.manager = CocoonComponentManager.getSitemapComponentManager();
577             this.sourceResolver = (org.apache.excalibur.source.SourceResolver)this.manager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);
578             if (this.tempInitContext != null) {
579                 org.apache.excalibur.source.Source source = null;
580                 try {
581                     source = this.sourceResolver.resolveURI(this.tempInitContext);
582                     this.context = source.getURI();
583
584                     if (this.rootContext == null) // hack for EnvironmentWrapper
585
this.rootContext = this.context;
586                 } finally {
587                     this.sourceResolver.release(source);
588                 }
589                 this.tempInitContext = null;
590             }
591         } catch (ComponentException ce) {
592             // this should never happen!
593
throw new CascadingRuntimeException("Unable to lookup component.", ce);
594         } catch (IOException JavaDoc ie) {
595             throw new CascadingRuntimeException("Unable to resolve URI: "+this.tempInitContext, ie);
596         }
597     }
598
599     /**
600      * Notify that the processing starts.
601      */

602     public void startingProcessing() {
603         // do nothing here
604
}
605
606     /**
607      * Notify that the processing is finished
608      * This can be used to cleanup the environment object
609      */

610     public void finishingProcessing() {
611         if (null != this.manager) {
612             this.manager.release(this.sourceResolver);
613             this.manager = null;
614             this.sourceResolver = null;
615         }
616         this.initializedComponents = false;
617     }
618
619     /* (non-Javadoc)
620      * @see org.apache.cocoon.environment.Environment#isInternRedirect()
621      */

622     public boolean isInternalRedirect() {
623         return false;
624     }
625 }
626
Popular Tags