KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lenya > cms > cocoon > transformation > SimpleLinkRewritingTransformer


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  */

17
18 /*
19  * $Id: SimpleLinkRewritingTransformer.java,v 1.7 2004/03/16 11:12:16 gregor
20  * Exp $
21  */

22
23 package org.apache.lenya.cms.cocoon.transformation;
24
25 import java.io.IOException JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.regex.Matcher JavaDoc;
28 import java.util.regex.Pattern JavaDoc;
29
30 import org.apache.avalon.framework.parameters.Parameters;
31 import org.apache.avalon.framework.activity.Disposable;
32 import org.apache.avalon.framework.service.ServiceSelector;
33 import org.apache.cocoon.ProcessingException;
34 import org.apache.cocoon.environment.ObjectModelHelper;
35 import org.apache.cocoon.environment.Request;
36 import org.apache.cocoon.environment.SourceResolver;
37 import org.apache.cocoon.transformation.AbstractSAXTransformer;
38 import org.apache.lenya.ac.AccessControlException;
39 import org.apache.lenya.ac.AccessController;
40 import org.apache.lenya.ac.AccessControllerResolver;
41 import org.apache.lenya.ac.AccreditableManager;
42 import org.apache.lenya.ac.Authorizer;
43 import org.apache.lenya.ac.Identity;
44 import org.apache.lenya.ac.Policy;
45 import org.apache.lenya.ac.PolicyManager;
46 import org.apache.lenya.ac.impl.DefaultAccessController;
47 import org.apache.lenya.ac.impl.PolicyAuthorizer;
48 import org.apache.lenya.cms.publication.DocumentBuilder;
49 import org.apache.lenya.cms.publication.PageEnvelope;
50 import org.apache.lenya.cms.publication.PageEnvelopeException;
51 import org.apache.lenya.cms.publication.PageEnvelopeFactory;
52 import org.apache.lenya.cms.publication.Publication;
53 import org.apache.lenya.cms.publication.PublicationException;
54 import org.apache.lenya.util.ServletHelper;
55 import org.xml.sax.Attributes JavaDoc;
56 import org.xml.sax.SAXException JavaDoc;
57 import org.xml.sax.helpers.AttributesImpl JavaDoc;
58 import org.apache.log4j.Category;
59
60
61 /**
62  * This is a simple transformer which rewrites <a
63  * HREF="../../../../../../../context/publication/authoring/doctypes/2columns.html"> to <a
64  * HREF="../../../../../../../context/publication/$AREA/doctypes/2columns.html">.
65  *
66  * It also checks if the target of the link really exists if the area is
67  * "live". If the link target doesn't exist the link will be inactive.
68  *
69  * Furthermore, you can define the live-prefix in your publication.xconf, and
70  * the transformer will use it for rewriting the live links if it is available.
71  *
72  * Ideally this transformer could be replaced by the LinkRewrittingTransformer
73  * that Forrest uses if we employ the same scheme for internal links.
74  *
75  * @deprecated Use the {@link org.apache.lenya.cms.cocoon.transformation.LinkRewritingTransformer} instead.
76  */

77 public class SimpleLinkRewritingTransformer extends AbstractSAXTransformer
78 implements Disposable {
79
80     Category log = Category.getInstance(SimpleLinkRewritingTransformer.class);
81
82     private String JavaDoc baseURI;
83     private PageEnvelope envelope = null;
84
85     public static final String JavaDoc INTERNAL_LINK_PREFIX = "site:";
86     private boolean ignoreAElement = false;
87
88     private ServiceSelector serviceSelector;
89     private PolicyManager policyManager;
90     private AccessControllerResolver acResolver;
91     private AccreditableManager accreditableManager;
92     private Identity identity;
93     private String JavaDoc urlPrefix;
94     private String JavaDoc sslPrefix;
95     private String JavaDoc liveMountPoint;
96     private String JavaDoc host;
97     private int port;
98
99     /**
100      * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver,
101      * java.util.Map, java.lang.String,
102      * org.apache.avalon.framework.parameters.Parameters)
103      */

104     public void setup(
105         SourceResolver resolver,
106         Map JavaDoc objectModel,
107         String JavaDoc source,
108         Parameters parameters)
109         throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
110
111         super.setup(resolver, objectModel, source, parameters);
112
113         try {
114             envelope =
115                 PageEnvelopeFactory.getInstance().getPageEnvelope(objectModel);
116         } catch (PageEnvelopeException e) {
117             throw new ProcessingException(e);
118         }
119
120         String JavaDoc mountPoint =
121             envelope.getContext() + "/" + envelope.getPublication().getId();
122         
123         sslPrefix = envelope.getPublication().getSSLPrefix();
124
125         liveMountPoint = envelope.getPublication().getLiveMountPoint();
126
127         StringBuffer JavaDoc uribuf = new StringBuffer JavaDoc();
128
129         uribuf.append(mountPoint);
130
131         baseURI = uribuf.toString();
132         
133         Request request = ObjectModelHelper.getRequest(objectModel);
134         
135         host = request.getServerName();
136         port = request.getServerPort();
137
138         serviceSelector = null;
139         acResolver = null;
140         policyManager = null;
141
142         identity = Identity.getIdentity(request.getSession(false));
143
144         try {
145             String JavaDoc publicationId = envelope.getPublication().getId();
146             String JavaDoc area = envelope.getDocument().getArea();
147
148                 getLogger().debug("Setting up transformer");
149                 getLogger().debug(" Identity: [" + identity + "]");
150                 getLogger().debug(" Publication ID: [" + publicationId + "]");
151                 getLogger().debug(" Area: [" + area + "]");
152
153             urlPrefix = "/" + publicationId + "/" + area;
154
155             serviceSelector =
156                 (ServiceSelector) manager.lookup(AccessControllerResolver.ROLE + "Selector");
157
158             acResolver =
159                 (AccessControllerResolver) serviceSelector.select(
160                     AccessControllerResolver.DEFAULT_RESOLVER);
161
162                 getLogger().debug(" Resolved AC resolver [" + acResolver + "]");
163
164             String JavaDoc webappUrl = ServletHelper.getWebappURI(request);
165             AccessController accessController = acResolver.resolveAccessController(webappUrl);
166
167             if (accessController instanceof DefaultAccessController) {
168                 DefaultAccessController defaultAccessController =
169                     (DefaultAccessController) accessController;
170
171                 accreditableManager = defaultAccessController.getAccreditableManager();
172
173                 Authorizer[] authorizers = defaultAccessController.getAuthorizers();
174                 for (int i = 0; i < authorizers.length; i++) {
175                     if (authorizers[i] instanceof PolicyAuthorizer) {
176                         PolicyAuthorizer policyAuthorizer = (PolicyAuthorizer) authorizers[i];
177                         policyManager = policyAuthorizer.getPolicyManager();
178                     }
179                 }
180             }
181
182                 getLogger().debug(" Using policy manager [" + policyManager + "]");
183
184         } catch (Exception JavaDoc e) {
185             throw new ProcessingException(e);
186         }
187     }
188
189     public void startElement(
190         String JavaDoc uri,
191         String JavaDoc name,
192         String JavaDoc qname,
193         Attributes JavaDoc attrs)
194         throws SAXException JavaDoc {
195         AttributesImpl JavaDoc newAttrs = null;
196
197         // FIXME: This pattern is extremely similar to the pattern in
198
// org.apache.lenya.cms.publication.xsp.DocumentReferencesHelper and
199
// has the
200
// same problems. See
201
// DocumentReferencesHelper#getInternalLinkPattern().
202
Pattern JavaDoc pattern =
203             Pattern.compile(
204                 envelope.getContext()
205                     + "/"
206                     + envelope.getPublication().getId()
207                     + "/"
208                     + Publication.AUTHORING_AREA
209                     + "(/[-a-zA-Z0-9_/]+?)(_[a-z][a-z])?\\.html");
210
211         if (lookingAtAElement(name)) {
212             for (int i = 0, size = attrs.getLength(); i < size; i++) {
213                 String JavaDoc attrName = attrs.getLocalName(i);
214                 if (attrName.equals("href")) {
215                     String JavaDoc value = attrs.getValue(i);
216
217                     Matcher JavaDoc matcher = pattern.matcher(value);
218                     if (matcher.find()) {
219                         // yes, this is an internal link that we need to
220
// rewrite
221
if (newAttrs == null)
222                             newAttrs = new AttributesImpl JavaDoc(attrs);
223
224                         String JavaDoc languageExtension = "";
225                         if (matcher.group(2) != null) {
226                             languageExtension = matcher.group(2);
227                         }
228
229                         String JavaDoc documentId = matcher.group(1);
230                         
231                         if (areaIsLive()) {
232                             if (!documentIsLive(documentId, languageExtension)) {
233                                 // deactivate the link if the link target is not live
234
ignoreAElement = true;
235                             } else {
236                                 // document is live
237
//if ssl, add prefix, if not, check for live mount point and apply if present
238
try {
239                                     String JavaDoc url = urlPrefix + documentId;
240                                     Policy policy = policyManager.getPolicy(accreditableManager, url);
241                                     if (policy.isSSLProtected()) {
242                                             log.debug(" live is SSL protected");
243                                      // add prefix
244
newAttrs.setValue(
245                                                 i,
246                                                 sslPrefix + documentId + languageExtension + ".html");
247                                     }
248                                     else {
249                                         // check for live mount point
250
newAttrs.setValue(
251                                         i,
252                                         getNewHrefValue(languageExtension, documentId));
253                                     }
254                                     
255                                     }
256                                     catch (AccessControlException e) {
257                                       throw new SAXException JavaDoc(e);
258                                     }
259
260                             }
261                         } else {
262                             /* authoring area
263                              */

264                             try {
265                                 String JavaDoc url = urlPrefix + documentId;
266                                 String JavaDoc finalurl;
267                                 Policy policy = policyManager.getPolicy(accreditableManager, url);
268                                 if (policy.isSSLProtected()) {
269                                  // add prefix
270
log.debug(" authoring is SSL protected");
271                                         log.debug(" ssl prefix: " + sslPrefix);
272                                         finalurl = sslPrefix + documentId + languageExtension + ".html";
273                                         log.debug(" finalurl: " + finalurl);
274                                     newAttrs.setValue(
275                                             i, finalurl
276                                             );
277                                 } else {
278                                         log.debug(" authoring is NOT SSL protected");
279                                     newAttrs.setValue(
280                                             i,
281                                             getNewHrefValue(languageExtension, documentId));
282                                 }
283                             }
284                             catch (AccessControlException e) {
285                               throw new SAXException JavaDoc(e);
286                             }
287                         }
288                     }
289                 }
290             }
291         }
292
293         if (!ignoreAElement) {
294             if (newAttrs == null) {
295                 super.startElement(uri, name, qname, attrs);
296             } else {
297                 super.startElement(uri, name, qname, newAttrs);
298             }
299         }
300     }
301
302     /**
303      * (non-Javadoc)
304      *
305      * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
306      * java.lang.String, java.lang.String)
307      */

308     public void endElement(String JavaDoc uri, String JavaDoc name, String JavaDoc qname)
309         throws SAXException JavaDoc {
310         if (lookingAtAElement(name) && ignoreAElement) {
311             ignoreAElement = false;
312         } else {
313             super.endElement(uri, name, qname);
314         }
315     }
316
317     private boolean lookingAtAElement(String JavaDoc name) {
318         return name.equals("a");
319     }
320
321     private boolean areaIsLive() {
322         return envelope.getDocument().getArea().equals(Publication.LIVE_AREA);
323     }
324
325     /**
326      * @param documentId
327      * @return true if the specified document id is live
328      */

329     private boolean documentIsLive(String JavaDoc documentId, String JavaDoc languageExtension)
330         throws SAXException JavaDoc {
331         boolean result = false;
332         DocumentBuilder builder =
333             envelope.getPublication().getDocumentBuilder();
334
335         // trim the '_'
336
String JavaDoc language =
337             (languageExtension == "") ? null : languageExtension.substring(1);
338         String JavaDoc url =
339             (language == null)
340                 ? builder.buildCanonicalUrl(
341                     envelope.getPublication(),
342                     Publication.LIVE_AREA,
343                     documentId)
344                 : builder.buildCanonicalUrl(
345                     envelope.getPublication(),
346                     Publication.LIVE_AREA,
347                     documentId,
348                     language);
349         try {
350             result =
351                 builder.buildDocument(envelope.getPublication(), url).exists();
352         } catch (PublicationException e) {
353             throw new SAXException JavaDoc(e);
354         }
355         return result;
356     }
357
358     private String JavaDoc getNewHrefValue(
359         String JavaDoc languageExtension,
360         String JavaDoc documentId) {
361         String JavaDoc preURL;
362         /*
363          * FIXME: this should really use the documentBuilder to build the url
364          */

365         
366         // the mount point is enabled, use it for live links
367
if (!liveMountPoint.equals("") && areaIsLive()) {
368             // dont prepend / because the documentid is already /document
369
if (liveMountPoint.equals("/")) {
370                 return documentId
371                 + languageExtension
372                 + ".html";
373             }
374             return liveMountPoint
375             + documentId
376             + languageExtension
377             + ".html";
378         }
379         
380        /* no mount point is defined. check if SSL prefix is defined and if yes, prepend
381         * all links with host to make it possible to distinguish between SSL and
382         * non SSL pages.
383         */

384         preURL = "";
385         if (!sslPrefix.equals("")) preURL = "http://" + host + ":" + port;
386
387         return preURL + baseURI
388             + "/"
389             + envelope.getDocument().getArea()
390             + documentId
391             + languageExtension
392             + ".html";
393     }
394
395     /**
396      * @see org.apache.avalon.framework.activity.Disposable#dispose()
397      */

398     public void dispose() {
399         if (getLogger().isDebugEnabled()) {
400             getLogger().debug("Disposing transformer");
401         }
402         if (serviceSelector != null) {
403             if (acResolver != null) {
404                 serviceSelector.release(acResolver);
405             }
406             manager.release(serviceSelector);
407         }
408     }
409
410     public void recycle() {
411         this.envelope = null;
412         this.baseURI = null;
413         this.ignoreAElement = false;
414     }
415 }
416
Popular Tags