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: package org.apache.cocoon.portal.impl;
018:
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.ArrayList;
022:
023: import org.apache.cocoon.portal.event.Event;
024: import org.apache.cocoon.portal.event.impl.ChangeAspectDataEvent;
025: import org.apache.cocoon.portal.layout.CompositeLayout;
026: import org.apache.cocoon.portal.layout.Item;
027: import org.apache.cocoon.portal.layout.NamedItem;
028: import org.apache.cocoon.environment.Request;
029: import org.apache.cocoon.components.ContextHelper;
030: import org.apache.avalon.framework.service.ServiceException;
031: import org.apache.avalon.framework.service.ServiceManager;
032:
033: /**
034: * The PageLabelLinkService generates links for named items defined in the layout portal.xml. Links
035: * for other entities are passed to the DefaultLinkService to be resolved.
036: *
037: * @author Ralph Goers
038: * @version CVS $Id:$
039: */
040: public class PageLabelLinkService extends DefaultLinkService {
041:
042: protected String apectName;
043:
044: /**
045: * The label manager
046: */
047: protected PageLabelManager labelManager;
048:
049: /* (non-Javadoc)
050: * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
051: */
052: public void service(ServiceManager manager) throws ServiceException {
053: super .service(manager);
054: this .labelManager = (PageLabelManager) this .manager
055: .lookup(PageLabelManager.ROLE);
056: }
057:
058: /**
059: * @see org.apache.cocoon.portal.LinkService#getLinkURI(java.util.List)
060: */
061: public String getLinkURI(List events, Boolean secure) {
062: List eventList = new ArrayList();
063: Iterator iter = events.iterator();
064: Event aspectEvent = null;
065: while (iter.hasNext()) {
066: Event event = (Event) iter.next();
067: if (event instanceof ChangeAspectDataEvent
068: && ((ChangeAspectDataEvent) event).getTarget() instanceof CompositeLayout) {
069: aspectEvent = event;
070: } else {
071: eventList.add(event);
072: }
073: }
074: if (aspectEvent != null) {
075: eventList.add(0, aspectEvent);
076: }
077: return super .getLinkURI(eventList, secure);
078: }
079:
080: protected String initBuffer(LinkInfo info, Event event,
081: Boolean secure) {
082: StringBuffer base = new StringBuffer(info.getBase(secure));
083: if (this .labelManager == null || !this .labelManager.isUrlPath()) {
084: return base.toString();
085: }
086:
087: String label;
088: if (event != null
089: && event instanceof ChangeAspectDataEvent
090: && ((ChangeAspectDataEvent) event).getTarget() instanceof CompositeLayout) {
091: label = getLabel((ChangeAspectDataEvent) event);
092: } else {
093: label = this .labelManager.getCurrentLabel();
094: }
095: if (label.length() > 0) {
096: base.setLength(0);
097: base.append(label);
098: }
099:
100: return base.toString();
101: }
102:
103: protected String initBuffer(LinkInfo info, List events,
104: Boolean secure) {
105: if (this .labelManager == null || !this .labelManager.isUrlPath()) {
106: return info.getBase(secure);
107: }
108:
109: Iterator iter = events.iterator();
110: Event aspectEvent = null;
111: while (iter.hasNext()) {
112: Event event = (Event) iter.next();
113: if (event instanceof ChangeAspectDataEvent
114: && ((ChangeAspectDataEvent) event).getTarget() instanceof CompositeLayout) {
115: aspectEvent = event;
116: }
117: }
118: return initBuffer(info, aspectEvent, secure);
119: }
120:
121: /**
122: * Add one event to the buffer
123: *
124: * @return Returns true, if the link contains a parameter
125: */
126: protected boolean addEvent(StringBuffer buffer, Event event,
127: boolean hasParams) {
128: if (this .labelManager != null
129: && this .labelManager.isUrlPath()
130: && event instanceof ChangeAspectDataEvent
131: && ((ChangeAspectDataEvent) event).getTarget() instanceof CompositeLayout) {
132: return true;
133: }
134:
135: return super .addEvent(buffer, event, hasParams);
136: }
137:
138: protected String processEvent(Event event, StringBuffer value) {
139: if (this .labelManager != null
140: && event instanceof ChangeAspectDataEvent
141: && ((ChangeAspectDataEvent) event).getTarget() instanceof CompositeLayout) {
142: value.append(getLabel((ChangeAspectDataEvent) event));
143: return this .labelManager.getRequestParameterName();
144: }
145: return super .processEvent(event, value);
146: }
147:
148: /* (non-Javadoc)
149: * @see org.apache.avalon.framework.activity.Disposable#dispose()
150: */
151: public void dispose() {
152: if (this .manager != null) {
153: if (this .labelManager != null) {
154: this .manager.release(this .labelManager);
155: this .labelManager = null;
156: }
157: }
158: super .dispose();
159: }
160:
161: /**
162: * Return the current info for the request.
163: *
164: * @return A LinkInfo object.
165: */
166: protected LinkInfo getInfo() {
167: if (!labelManager.isUrlPath()) {
168: return super .getInfo();
169: }
170: final Request request = ContextHelper.getRequest(this .context);
171: LinkInfo info = (LinkInfo) request
172: .getAttribute(DefaultLinkService.class.getName());
173: if (info == null) {
174: synchronized (this ) {
175: info = (LinkInfo) request
176: .getAttribute(DefaultLinkService.class
177: .getName());
178: if (info == null) {
179: info = new PageLabelLinkInfo(labelManager, request,
180: this .defaultPort, this .defaultSecurePort);
181: request.setAttribute(DefaultLinkService.class
182: .getName(), info);
183: }
184: }
185: }
186: return info;
187: }
188:
189: private String getLabel(ChangeAspectDataEvent event) {
190: CompositeLayout layout = (CompositeLayout) event.getTarget();
191: int i = ((Integer) event.getData()).intValue();
192:
193: Item item = layout.getItem(i);
194: StringBuffer key = new StringBuffer("");
195: if (item instanceof NamedItem) {
196: getKey(item, key);
197: }
198: return key.toString();
199: }
200:
201: /*
202: * Generates the page label.
203: * @param item An Item.
204: * @param key The StringBuffer in which to create the page label.
205: */
206: private void getKey(Item item, StringBuffer key) {
207: CompositeLayout parentLayout = item.getParent();
208: Item parentItem = parentLayout.getParent();
209:
210: if (parentItem != null) {
211: getKey(parentItem, key);
212: }
213:
214: if (key.length() > 0) {
215: key.append('.');
216: }
217: if (item instanceof NamedItem) {
218: key.append(((NamedItem) item).getName());
219: } else {
220: key.append(parentLayout.getItems().indexOf(item));
221: }
222: }
223: }
|