001: /*
002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/xml/types/CmsXmlVarLinkValue.java,v $
003: * Date : $Date: 2008-02-27 12:05:29 $
004: * Version: $Revision: 1.8 $
005: *
006: * This library is part of OpenCms -
007: * the Open Source Content Management System
008: *
009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010: *
011: * This library is free software; you can redistribute it and/or
012: * modify it under the terms of the GNU Lesser General Public
013: * License as published by the Free Software Foundation; either
014: * version 2.1 of the License, or (at your option) any later version.
015: *
016: * This library is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: * Lesser General Public License for more details.
020: *
021: * For further information about Alkacon Software GmbH, please see the
022: * company website: http://www.alkacon.com
023: *
024: * For further information about OpenCms, please see the
025: * project website: http://www.opencms.org
026: *
027: * You should have received a copy of the GNU Lesser General Public
028: * License along with this library; if not, write to the Free Software
029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
030: */
031:
032: package org.opencms.xml.types;
033:
034: import org.opencms.file.CmsObject;
035: import org.opencms.main.CmsIllegalArgumentException;
036: import org.opencms.main.CmsRuntimeException;
037: import org.opencms.main.OpenCms;
038: import org.opencms.relations.CmsLink;
039: import org.opencms.relations.CmsLinkUpdateUtil;
040: import org.opencms.relations.CmsRelationType;
041: import org.opencms.util.CmsRequestUtil;
042: import org.opencms.util.CmsStringUtil;
043: import org.opencms.xml.I_CmsXmlDocument;
044: import org.opencms.xml.page.CmsXmlPage;
045:
046: import java.util.Locale;
047:
048: import org.dom4j.Attribute;
049: import org.dom4j.Element;
050:
051: /**
052: * Describes the XML content type "OpenCmsVarLink".<p>
053: *
054: * This type allows a link to either an internal VFS resource, or to an external website.<p>
055: *
056: * @author Alexander Kandzior
057: *
058: * @version $Revision: 1.8 $
059: *
060: * @since 7.0.0
061: */
062: public class CmsXmlVarLinkValue extends A_CmsXmlContentValue {
063:
064: /** Value to mark that no link is defined, "none". */
065: public static final String NO_LINK = "none";
066:
067: /** The name of this type as used in the XML schema. */
068: public static final String TYPE_NAME = "OpenCmsVarLink";
069:
070: /** The schema definition String is located in a text for easier editing. */
071: private static String m_schemaDefinition;
072:
073: /** The link object represented by this object. */
074: private CmsLink m_linkValue;
075:
076: /** The String value of the element node. */
077: private String m_stringValue;
078:
079: /**
080: * Creates a new, empty schema type descriptor of type "OpenCmsVfsFile".<p>
081: */
082: public CmsXmlVarLinkValue() {
083:
084: // empty constructor is required for class registration
085: }
086:
087: /**
088: * Creates a new XML content value of type "OpenCmsVfsFile".<p>
089: *
090: * @param document the XML content instance this value belongs to
091: * @param element the XML element that contains this value
092: * @param locale the locale this value is created for
093: * @param type the type instance to create the value for
094: */
095: public CmsXmlVarLinkValue(I_CmsXmlDocument document,
096: Element element, Locale locale, I_CmsXmlSchemaType type) {
097:
098: super (document, element, locale, type);
099: }
100:
101: /**
102: * Creates a new schema type descriptor for the type "OpenCmsVfsFile".<p>
103: *
104: * @param name the name of the XML node containing the value according to the XML schema
105: * @param minOccurs minimum number of occurrences of this type according to the XML schema
106: * @param maxOccurs maximum number of occurrences of this type according to the XML schema
107: */
108: public CmsXmlVarLinkValue(String name, String minOccurs,
109: String maxOccurs) {
110:
111: super (name, minOccurs, maxOccurs);
112: }
113:
114: /**
115: * @see org.opencms.xml.types.A_CmsXmlContentValue#createValue(I_CmsXmlDocument, org.dom4j.Element, Locale)
116: */
117: public I_CmsXmlContentValue createValue(I_CmsXmlDocument document,
118: Element element, Locale locale) {
119:
120: return new CmsXmlVarLinkValue(document, element, locale, this );
121: }
122:
123: /**
124: * @see org.opencms.xml.types.I_CmsXmlSchemaType#generateXml(org.opencms.file.CmsObject, org.opencms.xml.I_CmsXmlDocument, org.dom4j.Element, java.util.Locale)
125: */
126: public Element generateXml(CmsObject cms,
127: I_CmsXmlDocument document, Element root, Locale locale) {
128:
129: Element element = root.addElement(getName());
130:
131: // get the default value from the content handler
132: String defaultValue = document.getContentDefinition()
133: .getContentHandler().getDefault(cms, this , locale);
134: if (defaultValue != null) {
135: I_CmsXmlContentValue value = createValue(document, element,
136: locale);
137: value.setStringValue(cms, defaultValue);
138: }
139: return element;
140: }
141:
142: /**
143: * Returns the link object represented by this XML content value.<p>
144: *
145: * @param cms the cms context, can be <code>null</code> but in this case no link check is performed,
146: * and the target is marked as "external"
147: *
148: * @return the link object represented by this XML content value
149: */
150: public CmsLink getLink(CmsObject cms) {
151:
152: if (m_linkValue == null) {
153: // need to to calculate link value twice
154: Element linkElement = m_element
155: .element(CmsXmlPage.NODE_LINK);
156: if (linkElement == null) {
157: setStringValue(cms, m_element.getText());
158: } else {
159: CmsLinkUpdateUtil.updateType(linkElement,
160: getContentDefinition().getContentHandler()
161: .getRelationType(this ));
162: CmsLink link = new CmsLink(linkElement);
163: if (link.isInternal()) {
164: // link management check
165: link.checkConsistency(cms);
166: }
167: if (CmsStringUtil.isEmptyOrWhitespaceOnly(link
168: .getTarget())) {
169: // this may just be an anchor link
170: m_linkValue = CmsLink.NULL_LINK;
171: } else {
172: m_linkValue = link;
173: }
174: }
175: }
176: if (m_linkValue == CmsLink.NULL_LINK) {
177: return null;
178: }
179: return m_linkValue;
180: }
181:
182: /**
183: * @see org.opencms.xml.types.I_CmsXmlContentValue#getPlainText(org.opencms.file.CmsObject)
184: */
185: public String getPlainText(CmsObject cms) {
186:
187: return getStringValue(cms);
188: }
189:
190: /**
191: * @see org.opencms.xml.types.I_CmsXmlSchemaType#getSchemaDefinition()
192: */
193: public String getSchemaDefinition() {
194:
195: // the schema definition is located in a separate file for easier editing
196: if (m_schemaDefinition == null) {
197: m_schemaDefinition = readSchemaDefinition("org/opencms/xml/types/XmlVfsFileValue.xsd");
198: }
199: return m_schemaDefinition;
200: }
201:
202: /**
203: * @see org.opencms.xml.types.I_CmsXmlContentValue#getStringValue(CmsObject)
204: */
205: public String getStringValue(CmsObject cms)
206: throws CmsRuntimeException {
207:
208: if (m_stringValue == null) {
209: m_stringValue = createStringValue(cms);
210: }
211: return m_stringValue;
212: }
213:
214: /**
215: * @see org.opencms.xml.types.A_CmsXmlContentValue#getTypeName()
216: */
217: public String getTypeName() {
218:
219: return TYPE_NAME;
220: }
221:
222: /**
223: * @see org.opencms.xml.types.A_CmsXmlContentValue#isSearchable()
224: */
225: public boolean isSearchable() {
226:
227: // there is no point in searching link values
228: return false;
229: }
230:
231: /**
232: * @see org.opencms.xml.types.A_CmsXmlContentValue#newInstance(java.lang.String, java.lang.String, java.lang.String)
233: */
234: public I_CmsXmlSchemaType newInstance(String name,
235: String minOccurs, String maxOccurs) {
236:
237: return new CmsXmlVarLinkValue(name, minOccurs, maxOccurs);
238: }
239:
240: /**
241: * @see org.opencms.xml.types.A_CmsXmlContentValue#setStringValue(org.opencms.file.CmsObject, java.lang.String)
242: */
243: public void setStringValue(CmsObject cms, String value)
244: throws CmsIllegalArgumentException {
245:
246: // element is rebuild from given String value below
247: m_element.clearContent();
248: // link value is re-calculated below
249: m_linkValue = null;
250: // ensure the String value is re-calculated next time it's needed
251: m_stringValue = null;
252: if (CmsStringUtil.isEmptyOrWhitespaceOnly(value)) {
253: // no valid value given
254: return;
255: }
256: String path = value;
257: if (cms != null) {
258: String siteRoot = OpenCms.getSiteManager().getSiteRoot(
259: value);
260: String oldSite = cms.getRequestContext().getSiteRoot();
261: try {
262: if (siteRoot != null) {
263: // only switch the site if needed
264: cms.getRequestContext().setSiteRoot(siteRoot);
265: // remove the site root, because the link manager call will append it anyway
266: path = cms.getRequestContext()
267: .removeSiteRoot(value);
268: }
269: // remove parameters, if not the link manager call might fail
270: String query = "";
271: int pos = path.indexOf(CmsRequestUtil.URL_DELIMITER);
272: int anchorPos = path.indexOf('#');
273: if ((pos == -1)
274: || ((anchorPos > -1) && (pos > anchorPos))) {
275: pos = anchorPos;
276: }
277: if (pos > -1) {
278: query = path.substring(pos);
279: path = path.substring(0, pos);
280: }
281: // get the root path
282: path = OpenCms.getLinkManager().getRootPath(cms, path);
283: if (path != null) {
284: // append parameters again
285: path += query;
286: }
287: } finally {
288: if (siteRoot != null) {
289: cms.getRequestContext().setSiteRoot(oldSite);
290: }
291: }
292: }
293: boolean internal = (path != null);
294: CmsRelationType type;
295: if (internal) {
296: type = getContentDefinition().getContentHandler()
297: .getRelationType(this );
298: } else {
299: // use original value for external links
300: path = value;
301: // external links are always "weak"
302: type = CmsRelationType.XML_WEAK;
303: }
304: CmsLink link = new CmsLink("varLink", type, path, internal);
305: if (internal) {
306: // link management check for internal links
307: link.checkConsistency(cms);
308: }
309: // update xml node
310: CmsLinkUpdateUtil.updateXmlForHtmlValue(link, null, m_element
311: .addElement(CmsXmlPage.NODE_LINK));
312: // store the calculated link
313: m_linkValue = link;
314: }
315:
316: /**
317: * Creates the String value for this VarLink value element.<p>
318: *
319: * @param cms the current users OpenCms context
320: *
321: * @return the String value for this VarLink value element
322: */
323: private String createStringValue(CmsObject cms) {
324:
325: Attribute enabled = m_element
326: .attribute(CmsXmlPage.ATTRIBUTE_ENABLED);
327:
328: String content = "";
329: if ((enabled == null)
330: || Boolean.valueOf(enabled.getText()).booleanValue()) {
331: CmsLink link = getLink(cms);
332: if (link != null) {
333: content = link.getUri();
334: if (link.isInternal() && (cms != null)) {
335: // remove site root for internal links
336: content = cms.getRequestContext().removeSiteRoot(
337: link.getUri());
338: }
339: }
340: }
341: return content;
342: }
343: }
|