KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > blandware > atleap > webapp > taglib > core > content > ContentIteratorTag


1 /*
2  * Copyright 2004 Blandware (http://www.blandware.com)
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 com.blandware.atleap.webapp.taglib.core.content;
17
18 import com.blandware.atleap.common.Constants;
19 import com.blandware.atleap.model.core.ContentField;
20 import com.blandware.atleap.model.core.Layout;
21 import com.blandware.atleap.model.core.Page;
22 import com.blandware.atleap.service.core.ContentFieldManager;
23 import com.blandware.atleap.service.core.LayoutManager;
24 import com.blandware.atleap.service.core.PageManager;
25 import com.blandware.atleap.webapp.struts.ContentTilesRequestProcessor;
26 import com.blandware.atleap.webapp.struts.HeritableComponentDefinition;
27 import com.blandware.atleap.webapp.util.core.CacheUtil;
28 import com.blandware.atleap.webapp.util.core.WebappUtil;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.struts.Globals;
32 import org.apache.struts.tiles.ComponentDefinition;
33 import org.apache.struts.tiles.TilesUtil;
34 import org.springframework.context.ApplicationContext;
35 import org.springframework.web.context.support.WebApplicationContextUtils;
36
37 import javax.servlet.ServletContext JavaDoc;
38 import javax.servlet.http.HttpServletRequest JavaDoc;
39 import javax.servlet.jsp.JspTagException JavaDoc;
40 import javax.servlet.jsp.PageContext JavaDoc;
41 import javax.servlet.jsp.tagext.JspFragment JavaDoc;
42 import javax.servlet.jsp.tagext.SimpleTagSupport JavaDoc;
43 import java.io.IOException JavaDoc;
44 import java.util.ArrayList JavaDoc;
45 import java.util.Arrays JavaDoc;
46 import java.util.Collection JavaDoc;
47 import java.util.Collections JavaDoc;
48 import java.util.Iterator JavaDoc;
49 import java.util.LinkedList JavaDoc;
50 import java.util.List JavaDoc;
51 import java.util.Locale JavaDoc;
52
53 /**
54  * <p>Tag for iterating content field which identifier has special postfix (like
55  * array) e.g. cfidentifier[2]
56  * <br />
57  * The index of content field is of double type
58  * </p>
59  * <p>
60  * <ul>
61  * <li>
62  * <b>identifier</b> - part of identifier of field before '[' symbol
63  * </li>
64  * <li>
65  * <b>definition</b> - name of tiles definition to which a field may belong. If
66  * not specified, definition of current page is taken
67  * </li>
68  * <li>
69  * <b>uri</b> - URI of page to which a field may belong. If not specified, URI
70  * of current page is taken
71  * </li>
72  * <li>
73  * <b>locale</b> - identifier of content locale to use. If not specified, user
74  * locale is tried. If it's <code>null</code>, default locale is taken.
75  * </li>
76  * <li>
77  * <b>ignore</b> - If "true", then: 1) any exception will be ignored (for instance, when no
78  * definition is found at all, or no page with given URI exists); 2) If no
79  * indices were found, tag body will still be rendered 1 time. This can be
80  * "true" or "false", default is "false".
81  * </li>
82  * <li>
83  * <b>index</b> - name of page scope variable that will accept index of current
84  * field on each iteration
85  * </li>
86  * </ul>
87  * </p>
88  * <p>
89  * Here's an example:
90  * <pre>
91  * &lt;atleap:contentIterator identifier="leftBlock" index="index"&gt;
92  * &lt;div class="block"&gt;
93  * &lt;atleap:content identifier="leftBlock" index="${index}"/&gt;
94  * &lt;/div&gt;
95  * &lt;/atleap:contentIterator&gt;
96  * </pre>
97  * It will render content field values that belong to indexed field with
98  * identifier "leftBlock", which is owned by current page or its layout for
99  * current content locale.
100  * </p>
101  * <p><a HREF="ContentIteratorTag.java.htm"><i>View Source</i></a></p>
102  *
103  * @author Andrey Grebnev <a HREF="mailto:andrey.grebnev@blandware.com">&lt;andrey.grebnev@blandware.com&gt;</a>
104  * @author Sergey Zubtcovskii <a HREF="mailto:sergey.zubtcovskii@blandware.com">&lt;sergey.zubtcovskii@blandware.com&gt;</a>
105  * @version $Revision: 1.21 $ $Date: 2005/10/12 13:34:54 $
106  * @jsp.tag name="contentIterator"
107  * body-content="scriptless"
108  */

109 public class ContentIteratorTag extends SimpleTagSupport JavaDoc {
110
111     protected transient final Log log = LogFactory.getLog(ContentIteratorTag.class);
112
113     protected ApplicationContext applicationCtx = null;
114
115     /**
116      * Name of variable to export index
117      */

118     protected String JavaDoc index;
119
120     /**
121      * Identifier prefix of ContentField
122      */

123     protected String JavaDoc identifier = null;
124     /**
125      * Name of tiles definition to which a field may belong. If not specified,
126      * definition of current page is taken
127      */

128     protected String JavaDoc definition = null;
129     /**
130      * URI of page to which a field may belong. If not specified, URI of current
131      * page is taken
132      */

133     protected String JavaDoc uri = null;
134     /**
135      * Identifier of content locale to use. If not specified, user locale is
136      * tried. If it's <code>null</code>, default locale is taken.
137      */

138     protected String JavaDoc locale = null;
139     /**
140      * Name of page scope variable that will accept index of current field on
141      * each iteration
142      */

143     protected Boolean JavaDoc ignore = Boolean.FALSE;
144
145     protected Iterator JavaDoc fieldIndicesIterator = null;
146
147
148     /**
149      * Returns identifier of CF
150      *
151      * @return identifier
152      * @jsp.attribute required="true"
153      * rtexprvalue="true"
154      * type="java.lang.String"
155      * description="Identifier prefix of content field value"
156      */

157     public String JavaDoc getIdentifier() {
158         return identifier;
159     }
160
161     /**
162      * Sets identifier of CF
163      *
164      * @param identifier identifier to set
165      */

166     public void setIdentifier(String JavaDoc identifier) {
167         this.identifier = identifier;
168     }
169
170     /**
171      * Returns URI of page to which the field belongs
172      *
173      * @return URI of owner
174      * @jsp.attribute required="false"
175      * rtexprvalue="true"
176      * type="java.lang.String"
177      * description="URI of the page in database. By default it is uri of current processed page."
178      */

179     public String JavaDoc getUri() {
180         return uri;
181     }
182
183     /**
184      * Sets URI of page to which the field belongs
185      *
186      * @param uri URI of owner to set
187      */

188     public void setUri(String JavaDoc uri) {
189         this.uri = uri;
190     }
191
192     /**
193      * Returns tiles definition name of layout to which the field belogns
194      *
195      * @return tiles definition name
196      * @jsp.attribute required="false"
197      * rtexprvalue="true"
198      * type="java.lang.String"
199      * description="Definition name in database. By default it is definition of current processed page."
200      */

201     public String JavaDoc getDefinition() {
202         return definition;
203     }
204
205     /**
206      * Sets tiles definition name of layout to which the field belogns
207      *
208      * @param definition tiles definition name to set
209      */

210     public void setDefinition(String JavaDoc definition) {
211         this.definition = definition;
212     }
213
214     /**
215      * Returns name of variable to export index
216      *
217      * @return name of variable to export index
218      * @jsp.attribute required="true"
219      * rtexprvalue="true"
220      * type="java.lang.String"
221      * description="Name of variable to export index"
222      */

223     public String JavaDoc getIndex() {
224         return index;
225     }
226
227     /**
228      * Sets name of variable to export index
229      *
230      * @param index name of variable to export index to set
231      */

232     public void setIndex(String JavaDoc index) {
233         this.index = index;
234     }
235
236     /**
237      * Returns locale
238      *
239      * @return locale
240      * @jsp.attribute required="false"
241      * rtexprvalue="true"
242      * type="java.lang.Boolean"
243      * description="By default locale is used from session"
244      */

245     public String JavaDoc getLocale() {
246         return locale;
247     }
248
249     /**
250      * Sets locale
251      *
252      * @param locale locale to set
253      */

254     public void setLocale(String JavaDoc locale) {
255         this.locale = locale;
256     }
257
258     /**
259      * Returns whether to ignore errors
260      *
261      * @return whether to ignore errors
262      * @jsp.attribute required="false"
263      * rtexprvalue="true"
264      * type="java.lang.Boolean"
265      * description="If it is true and there are not fields the tag body will be shown one time"
266      */

267     public Boolean JavaDoc getIgnore() {
268         return ignore;
269     }
270
271     /**
272      * Sets whether to ignore errors
273      *
274      * @param ignore whether to ignore errors
275      */

276     public void setIgnore(Boolean JavaDoc ignore) {
277         this.ignore = ignore;
278     }
279
280     /**
281      * Constructs an iterator for indexed looping through the body once per
282      * element.
283      *
284      * @throws javax.servlet.jsp.JspTagException
285      * if a JSP exception has occurred
286      */

287     public void doTag() throws JspTagException JavaDoc, IOException JavaDoc {
288
289         PageContext JavaDoc pageContext = (PageContext JavaDoc) getJspContext();
290         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext.getRequest();
291         ServletContext JavaDoc servletContext = request.getSession().getServletContext();
292
293         try {
294
295             if ( log.isDebugEnabled() ) {
296                 log.debug("Start processing content fields.");
297             }
298
299             if ( applicationCtx == null ) {
300                 applicationCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(pageContext.getServletContext());
301             }
302
303             //get locale
304
if ( locale == null ) {
305                 Locale JavaDoc l = (Locale JavaDoc) pageContext.getAttribute(Globals.LOCALE_KEY, PageContext.SESSION_SCOPE);
306                 if ( l != null ) {
307                     locale = l.getLanguage();
308                 }
309             }
310             if ( locale == null ) {
311                 locale = Locale.getDefault().getLanguage();
312             }
313
314             // get definition
315
if ( definition != null ) {
316                 ComponentDefinition tmpDef = null;
317                 try {
318                     tmpDef = TilesUtil.getDefinition(definition, request, servletContext);
319                 } catch ( Exception JavaDoc ex ) {
320                     //do nothing
321
}
322                 if ( tmpDef == null ) {
323                     if ( ignore.booleanValue() ) {
324                         return;
325                     }
326                     String JavaDoc errorMessage = "Specified definition '" + definition + "' has not been found";
327                     JspTagException JavaDoc e = new JspTagException JavaDoc(errorMessage);
328                     throw e;
329                 }
330             } else {
331                 definition = (String JavaDoc) pageContext.getAttribute(ContentTilesRequestProcessor.DEFINITION_NAME, PageContext.REQUEST_SCOPE);
332             }
333             if ( definition == null ) {
334                 if ( ignore.booleanValue() ) {
335                     return;
336                 }
337                 String JavaDoc errorMessage = "DEFINITION_NAME attribute has not been found in request. This can be used only on pages processed by action using tile definition.";
338                 JspTagException JavaDoc e = new JspTagException JavaDoc(errorMessage);
339                 throw e;
340             }
341
342             //get uri
343
if ( uri != null ) {
344                 PageManager pageManager = (PageManager) applicationCtx.getBean(Constants.PAGE_MANAGER_BEAN);
345                 Page page = pageManager.findPageByUri(uri);
346                 if ( page == null ) {
347                     if ( ignore.booleanValue() ) {
348                         return;
349                     }
350                     String JavaDoc errorMessage = "Specified page uri '" + uri + "' has not been found";
351                     JspTagException JavaDoc e = new JspTagException JavaDoc(errorMessage);
352                     throw e;
353                 }
354             } else {
355                 uri = (String JavaDoc) pageContext.getAttribute(ContentTilesRequestProcessor.PROCESSED_URI, PageContext.REQUEST_SCOPE);
356             }
357             if ( uri == null ) {
358                 if ( ignore.booleanValue() ) {
359                     return;
360                 }
361                 String JavaDoc errorMessage = "PROCESSED_URI attribute has not been found in request. This can be used only on pages processed by action using tile definition.";
362                 JspTagException JavaDoc e = new JspTagException JavaDoc(errorMessage);
363                 throw e;
364             }
365
366             CacheUtil cacheUtil = CacheUtil.getInstance(request);
367
368             String JavaDoc[] fieldIndices = null;
369             fieldIndices = cacheUtil.getFieldIndices(identifier, locale, definition, uri);
370
371             if ( fieldIndices == null ) {
372                 //cache is empty or stale - try to get from database
373
if ( log.isDebugEnabled() ) {
374                     log.debug("Trying to search in database");
375                 }
376
377                 ContentFieldManager contentFieldManager = (ContentFieldManager) applicationCtx.getBean(Constants.CONTENT_FIELD_MANAGER_BEAN);
378                 LayoutManager layoutManager = (LayoutManager) applicationCtx.getBean(Constants.LAYOUT_MANAGER_BEAN);
379                 Collection JavaDoc allFields = null;
380
381                 List JavaDoc layouts = new ArrayList JavaDoc();
382                 String JavaDoc tmpDefinition = definition;
383                 do {
384                     Layout layout = layoutManager.findLayoutByDefinition(tmpDefinition);
385                     if ( layout != null ) {
386                         layouts.add(layout);
387                     }
388                     tmpDefinition = ((HeritableComponentDefinition) TilesUtil.getDefinition(tmpDefinition, request, servletContext)).getExtends();
389                 } while ( tmpDefinition != null );
390
391                 Collections.reverse(layouts);
392                 for ( int i = 0; i < layouts.size(); i++ ) {
393                     Layout layout = (Layout) layouts.get(i);
394                     List JavaDoc fields = contentFieldManager.findIndexedContentFieldsByLayoutDefinition(identifier, layout.getDefinition(), locale);
395                     if ( log.isDebugEnabled() && fields != null ) {
396                         log.debug("Using " + fields.size() + " fields from layout with definition: " + layout.getDefinition());
397                     }
398                     allFields = WebappUtil.joinFields(allFields, fields);
399                 }
400
401                 List JavaDoc pageFields = contentFieldManager.findIndexedContentFieldsByPageUri(identifier, uri, locale);
402                 if ( log.isDebugEnabled() && pageFields != null ) {
403                     log.debug("Using " + pageFields.size() + " fields from page with uri: " + uri);
404                 }
405                 allFields = WebappUtil.joinFields(allFields, pageFields);
406
407                 if ( allFields != null ) {
408                     List JavaDoc sortedFields = new LinkedList JavaDoc(allFields);
409                     Collections.sort(sortedFields, new WebappUtil.IndexedContentFieldComparator());
410
411                     if ( log.isDebugEnabled() ) {
412                         log.debug("Found " + allFields.size() + " fields for definition name: " + definition + ", locale: " + locale + ", uri: " + uri + ", identifier: " + identifier);
413                     }
414
415                     List JavaDoc fieldIndicesList = new ArrayList JavaDoc();
416
417                     for ( int i = 0; i < sortedFields.size(); i++ ) {
418                         ContentField contentField = (ContentField) sortedFields.get(i);
419                         String JavaDoc indexValue = WebappUtil.getContentFieldIndex(contentField.getIdentifier());
420                         if ( indexValue != null ) {
421                             fieldIndicesList.add(indexValue);
422                         }
423                     }
424
425                     fieldIndices = (String JavaDoc[]) fieldIndicesList.toArray(new String JavaDoc[]{});
426
427                     cacheUtil.putFieldIndicesInCache(fieldIndices, identifier, locale, definition, uri);
428                 }
429             }
430
431             if ( fieldIndices != null ) {
432                 fieldIndicesIterator = Arrays.asList(fieldIndices).iterator();
433             }
434
435             if ( fieldIndicesIterator != null ) {
436                 while ( fieldIndicesIterator.hasNext() ) {
437                     String JavaDoc indexValue = (String JavaDoc) fieldIndicesIterator.next();
438                     pageContext.setAttribute(index, indexValue);
439                     if ( log.isDebugEnabled() ) {
440                         log.debug("Putting as attribute with key=" + index + " and value=" + indexValue);
441                     }
442                     JspFragment JavaDoc body = getJspBody();
443                     if ( body != null ) {
444                         body.invoke(null);
445                     }
446                 }
447             } else {
448                 if ( ignore.booleanValue() ) {
449                     JspFragment JavaDoc body = getJspBody();
450                     if ( body != null ) {
451                         body.invoke(null);
452                     }
453                 }
454             }
455
456         } catch ( Exception JavaDoc ex ) {
457             if ( ex instanceof IOException JavaDoc ) {
458                 throw (IOException JavaDoc) ex;
459             }
460             JspTagException JavaDoc e = new JspTagException JavaDoc(ex);
461             throw e;
462         }
463
464         if ( index != null ) {
465             pageContext.removeAttribute(index);
466         }
467
468     }
469
470 }
471
Popular Tags