001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.lenya.cms.site.usecases;
019:
020: import java.text.DateFormat;
021: import java.text.SimpleDateFormat;
022: import java.util.ArrayList;
023: import java.util.Arrays;
024: import java.util.Collections;
025: import java.util.Comparator;
026: import java.util.Date;
027: import java.util.HashMap;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Map;
031: import java.util.SortedSet;
032: import java.util.TreeSet;
033:
034: import org.apache.avalon.framework.service.ServiceException;
035: import org.apache.avalon.framework.service.ServiceSelector;
036: import org.apache.lenya.cms.publication.Document;
037: import org.apache.lenya.cms.publication.DocumentFactory;
038: import org.apache.lenya.cms.publication.Publication;
039: import org.apache.lenya.cms.publication.PublicationException;
040: import org.apache.lenya.cms.publication.PublicationUtil;
041: import org.apache.lenya.cms.publication.ResourceType;
042: import org.apache.lenya.cms.repository.Node;
043: import org.apache.lenya.cms.site.SiteException;
044: import org.apache.lenya.cms.site.SiteManager;
045: import org.apache.lenya.cms.usecase.AbstractUsecase;
046: import org.apache.lenya.cms.usecase.UsecaseException;
047: import org.apache.lenya.cms.workflow.WorkflowUtil;
048: import org.apache.lenya.workflow.Version;
049: import org.apache.lenya.workflow.Workflow;
050: import org.apache.lenya.workflow.Workflowable;
051:
052: /**
053: * Overview over all documents.
054: */
055: public class SiteOverview extends AbstractUsecase {
056:
057: protected static final String ALL_DOCUMENTS = "allDocuments";
058: protected static final String DOCUMENTS = "documents";
059: protected static final String FILTER_WORKFLOW_STATE_VALUES = "filterWorkflowStateValues";
060: protected static final String FILTER_RESOURCE_TYPE_VALUES = "filterResourceTypeValues";
061:
062: protected static final String KEY_PATH = "keyPath";
063: protected static final String KEY_RESOURCE_TYPE = "keyResourceType";
064: protected static final String KEY_WORKFLOW_STATE = "keyWorkflowState";
065: protected static final String KEY_LANGUAGE = "keyLanguage";
066: protected static final String KEY_LAST_MODIFIED = "keyLastModified";
067: protected static final String KEY_URL = "keyUrl";
068: protected static final String KEY_CHECKED_OUT = "keyCheckedOut";
069: protected static final String PARAMETER_KEYS = "keys";
070:
071: protected static final String[] KEYS = { KEY_PATH, KEY_LANGUAGE,
072: KEY_RESOURCE_TYPE, KEY_WORKFLOW_STATE, KEY_LAST_MODIFIED,
073: KEY_CHECKED_OUT };
074:
075: protected static final String FILTER_RESOURCE_TYPE = "filterResourceType";
076: protected static final String FILTER_WORKFLOW_STATE = "filterWorkflowState";
077: protected static final String FILTER_LANGUAGE = "filterLanguage";
078: protected static final String PARAMETER_FILTERS = "filters";
079:
080: protected static final String[] FILTERS = { FILTER_LANGUAGE,
081: FILTER_RESOURCE_TYPE, FILTER_WORKFLOW_STATE };
082:
083: protected static final String VALUE_ALL = "- all -";
084:
085: protected static final String SORT = "sort";
086:
087: protected static final String ORDER = "order";
088:
089: protected static final String DESC = "desc";
090: protected static final String ASC = "asc";
091:
092: /**
093: * @see org.apache.lenya.cms.usecase.AbstractUsecase#initParameters()
094: */
095: protected void initParameters() {
096: super .initParameters();
097: try {
098: Document[] documents = getDocuments();
099:
100: List entries = new ArrayList();
101: for (int i = 0; i < documents.length; i++) {
102:
103: Entry entry = new Entry();
104: if (documents[i].hasLink()) {
105: entry.setValue(KEY_PATH, documents[i].getPath());
106: } else {
107: entry.setValue(KEY_PATH, "not in site structure");
108: }
109: entry.setValue(KEY_RESOURCE_TYPE,
110: ResourceType.I18N_PREFIX
111: + documents[i].getResourceType()
112: .getName());
113: entry
114: .setValue(KEY_LANGUAGE, documents[i]
115: .getLanguage());
116: entry.setValue(KEY_URL, documents[i]
117: .getCanonicalWebappURL());
118:
119: DateFormat format = new SimpleDateFormat(
120: "yyyy-MM-dd HH:mm:ss");
121: String lastModified = format.format(new Date(
122: documents[i].getLastModified()));
123: entry.setValue(KEY_LAST_MODIFIED, lastModified);
124:
125: if (WorkflowUtil.hasWorkflow(this .manager,
126: getSession(), getLogger(), documents[i])) {
127: Workflowable workflowable = WorkflowUtil
128: .getWorkflowable(this .manager,
129: getSession(), getLogger(),
130: documents[i]);
131: Version latestVersion = workflowable
132: .getLatestVersion();
133: String state;
134: if (latestVersion != null) {
135: state = latestVersion.getState();
136: } else {
137: Workflow workflow = WorkflowUtil
138: .getWorkflowSchema(this .manager,
139: getSession(), getLogger(),
140: documents[i]);
141: state = workflow.getInitialState();
142: }
143: entry.setValue(KEY_WORKFLOW_STATE, state);
144: } else {
145: entry.setValue(KEY_WORKFLOW_STATE, "");
146: }
147:
148: Node node = documents[i].getRepositoryNode();
149: if (node.isCheckedOut()) {
150: entry.setValue(KEY_CHECKED_OUT, node
151: .getCheckoutUserId());
152: } else {
153: entry.setValue(KEY_CHECKED_OUT, "");
154: }
155: entries.add(entry);
156: }
157:
158: for (int i = 0; i < FILTERS.length; i++) {
159: SortedSet filterValues = new TreeSet();
160: filterValues.add(VALUE_ALL);
161:
162: String key = "key"
163: + FILTERS[i].substring("filter".length());
164:
165: for (Iterator docs = entries.iterator(); docs.hasNext();) {
166: Entry entry = (Entry) docs.next();
167: filterValues.add(entry.getValue(key));
168: }
169: setParameter(FILTERS[i] + "Values", filterValues);
170: setParameter(FILTERS[i], VALUE_ALL);
171: }
172: setParameter(PARAMETER_FILTERS, Arrays.asList(FILTERS));
173:
174: setParameter(ALL_DOCUMENTS, new ArrayList(entries));
175: setParameter(DOCUMENTS, entries);
176:
177: setParameter(PARAMETER_KEYS, Arrays.asList(KEYS));
178:
179: } catch (Exception e) {
180: throw new RuntimeException(e);
181: }
182: }
183:
184: /**
185: * @return The documents in the authoring area.
186: * @throws PublicationException if an error occurs.
187: * @throws SiteException if an error occurs.
188: */
189: protected Document[] getDocuments() throws PublicationException,
190: SiteException {
191: Publication publication = getPublication();
192: DocumentFactory identityMap = getDocumentFactory();
193: Document[] documents;
194:
195: ServiceSelector selector = null;
196: SiteManager siteManager = null;
197: try {
198: selector = (ServiceSelector) this .manager
199: .lookup(SiteManager.ROLE + "Selector");
200: siteManager = (SiteManager) selector.select(publication
201: .getSiteManagerHint());
202: documents = siteManager.getDocuments(identityMap,
203: publication, Publication.AUTHORING_AREA);
204: } catch (ServiceException e) {
205: throw new RuntimeException(e);
206: } finally {
207: if (selector != null) {
208: if (siteManager != null) {
209: selector.release(siteManager);
210: }
211: this .manager.release(selector);
212: }
213: }
214:
215: return documents;
216: }
217:
218: /**
219: * @return The publication.
220: * @throws PublicationException if an error occurs.
221: */
222: protected Publication getPublication() throws PublicationException {
223: return PublicationUtil.getPublicationFromUrl(this .manager,
224: getDocumentFactory(), getSourceURL());
225: }
226:
227: /**
228: * @see org.apache.lenya.cms.usecase.Usecase#advance()
229: */
230: public void advance() throws UsecaseException {
231: super .advance();
232:
233: List allDocuments = (List) getParameter(ALL_DOCUMENTS);
234: List filteredDocuments = new ArrayList(allDocuments);
235:
236: for (int i = 0; i < FILTERS.length; i++) {
237: String key = "key"
238: + FILTERS[i].substring("filter".length());
239: String filterValue = getParameterAsString(FILTERS[i]);
240: if (!filterValue.equals(VALUE_ALL)) {
241: Entry[] entries = (Entry[]) filteredDocuments
242: .toArray(new Entry[filteredDocuments.size()]);
243: for (int entryIndex = 0; entryIndex < entries.length; entryIndex++) {
244: if (!entries[entryIndex].getValue(key).equals(
245: filterValue)) {
246: filteredDocuments.remove(entries[entryIndex]);
247: }
248: }
249: }
250: }
251:
252: String sort = getParameterAsString(SORT);
253: String order = getParameterAsString(ORDER, ASC);
254: if (sort != null) {
255: Comparator comparator = new EntryComparator(sort, order);
256: Collections.sort(filteredDocuments, comparator);
257: }
258:
259: setParameter(DOCUMENTS, filteredDocuments);
260: }
261:
262: /**
263: * Comparator for entries.
264: */
265: public static class EntryComparator implements Comparator {
266:
267: private String key;
268: private String order;
269:
270: /**
271: * @param key The key to compare.
272: * @param order The order string ({@link SiteOverview#ASC} or {@link SiteOverview#DESC}).
273: */
274: public EntryComparator(String key, String order) {
275: this .key = key;
276: this .order = order;
277: }
278:
279: /**
280: * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
281: */
282: public int compare(Object arg0, Object arg1) {
283: Entry e1 = (Entry) arg0;
284: Entry e2 = (Entry) arg1;
285:
286: String value1 = e1.getValue(this .key);
287: String value2 = e2.getValue(this .key);
288: if (this .order.equals(DESC))
289: return value2.compareTo(value1);
290: else
291: return value1.compareTo(value2);
292: }
293:
294: }
295:
296: /**
297: * Stores document-related information.
298: */
299: public static class Entry {
300:
301: private Map values = new HashMap();
302:
303: /**
304: * Ctor.
305: */
306: public Entry() {
307: }
308:
309: /**
310: * @param key The key.
311: * @param value The value.
312: */
313: public void setValue(String key, String value) {
314: this .values.put(key, value);
315: }
316:
317: /**
318: * @param key The key.
319: * @return The value.
320: */
321: public String getValue(String key) {
322: return (String) this.values.get(key);
323: }
324:
325: }
326:
327: }
|