001: /*
002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/staticexport/CmsLinkManager.java,v $
003: * Date : $Date: 2008-02-27 12:05:46 $
004: * Version: $Revision: 1.77 $
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.staticexport;
033:
034: import org.opencms.file.CmsObject;
035: import org.opencms.file.CmsProject;
036: import org.opencms.file.CmsResource;
037: import org.opencms.file.CmsResourceFilter;
038: import org.opencms.main.CmsException;
039: import org.opencms.main.CmsLog;
040: import org.opencms.main.CmsPermalinkResourceHandler;
041: import org.opencms.main.OpenCms;
042: import org.opencms.relations.CmsExternalLinksValidationResult;
043: import org.opencms.security.CmsRole;
044: import org.opencms.security.CmsRoleViolationException;
045: import org.opencms.site.CmsSite;
046: import org.opencms.util.CmsFileUtil;
047: import org.opencms.util.CmsStringUtil;
048:
049: import java.net.MalformedURLException;
050: import java.net.URL;
051:
052: import org.apache.commons.logging.Log;
053:
054: /**
055: * Does the link replacement for the ≶link> tags.<p>
056: *
057: * Since this functionality is closely related to the static export,
058: * this class resides in the static export package.<p>
059: *
060: * @author Alexander Kandzior
061: *
062: * @version $Revision: 1.77 $
063: *
064: * @since 6.0.0
065: */
066: public class CmsLinkManager {
067:
068: /** The log object for this class. */
069: private static final Log LOG = CmsLog.getLog(CmsLinkManager.class);
070:
071: /** Base URL to calculate absolute links. */
072: private static URL m_baseUrl;
073:
074: /** The configured link substitution handler. */
075: private I_CmsLinkSubstitutionHandler m_linkSubstitutionHandler;
076:
077: /** Stores the results of a external link validation. */
078: private CmsExternalLinksValidationResult m_pointerLinkValidationResult;
079:
080: /**
081: * Public constructor.<p>
082: *
083: * @param linkSubstitutionHandler the link substitution handler to use
084: */
085: public CmsLinkManager(
086: I_CmsLinkSubstitutionHandler linkSubstitutionHandler) {
087:
088: m_linkSubstitutionHandler = linkSubstitutionHandler;
089: if (m_linkSubstitutionHandler == null) {
090: // just make very sure that this is not null
091: m_linkSubstitutionHandler = new CmsDefaultLinkSubstitutionHandler();
092: }
093: }
094:
095: /**
096: * Static initializer for the base URL.<p>
097: */
098: static {
099: m_baseUrl = null;
100: try {
101: m_baseUrl = new URL("http://127.0.0.1");
102: } catch (MalformedURLException e) {
103: // this won't happen
104: }
105: }
106:
107: /**
108: * Calculates the absolute URI for the "relativeUri" with the given absolute "baseUri" as start. <p>
109: *
110: * If "relativeUri" is already absolute, it is returned unchanged.
111: * This method also returns "relativeUri" unchanged if it is not well-formed.<p>
112: *
113: * @param relativeUri the relative URI to calculate an absolute URI for
114: * @param baseUri the base URI, this must be an absolute URI
115: *
116: * @return an absolute URI calculated from "relativeUri" and "baseUri"
117: */
118: public static String getAbsoluteUri(String relativeUri,
119: String baseUri) {
120:
121: if (isAbsoluteUri(relativeUri)) {
122: // URI is null or already absolute
123: return relativeUri;
124: }
125: try {
126: URL url = new URL(new URL(m_baseUrl, baseUri), relativeUri);
127: StringBuffer result = new StringBuffer(100);
128: result.append(url.getPath());
129: if (url.getQuery() != null) {
130: result.append('?');
131: result.append(url.getQuery());
132: }
133: if (url.getRef() != null) {
134: result.append('#');
135: result.append(url.getRef());
136: }
137: return result.toString();
138: } catch (MalformedURLException e) {
139: return relativeUri;
140: }
141: }
142:
143: /**
144: * Calculates a relative URI from "fromUri" to "toUri",
145: * both URI must be absolute.<p>
146: *
147: * @param fromUri the URI to start
148: * @param toUri the URI to calculate a relative path to
149: * @return a relative URI from "fromUri" to "toUri"
150: */
151: public static String getRelativeUri(String fromUri, String toUri) {
152:
153: StringBuffer result = new StringBuffer();
154: int pos = 0;
155:
156: while (true) {
157: int i = fromUri.indexOf('/', pos);
158: int j = toUri.indexOf('/', pos);
159: if ((i == -1) || (i != j)
160: || !fromUri.regionMatches(pos, toUri, pos, i - pos)) {
161: break;
162: }
163: pos = i + 1;
164: }
165:
166: // count hops up from here to the common ancestor
167: for (int i = fromUri.indexOf('/', pos); i > 0; i = fromUri
168: .indexOf('/', i + 1)) {
169: result.append("../");
170: }
171:
172: // append path down from common ancestor to there
173: result.append(toUri.substring(pos));
174:
175: if (result.length() == 0) {
176: // special case: relative link to the parent folder from a file in that folder
177: result.append("./");
178: }
179:
180: return result.toString();
181: }
182:
183: /**
184: * Returns the resource root path for the given target URI in the OpenCms VFS, or <code>null</code> in
185: * case the target URI points to an external site.<p>
186: *
187: * @param cms the current users OpenCms context
188: * @param basePath path to use as base site for the target URI (can be <code>null</code>)
189: * @param targetUri the target URI
190: *
191: * @return the resource root path for the given target URI in the OpenCms VFS, or <code>null</code> in
192: * case the target URI points to an external site
193: *
194: * @deprecated use {@link #getRootPath(CmsObject, String, String)} instead, obtain the link manager
195: * with {@link OpenCms#getLinkManager()}
196: */
197: public static String getSitePath(CmsObject cms, String basePath,
198: String targetUri) {
199:
200: return OpenCms.getLinkManager().getRootPath(cms, targetUri,
201: basePath);
202: }
203:
204: /**
205: * Tests if the given URI starts with a scheme component.<p>
206: *
207: * The scheme component is something like <code>http:</code> or <code>ftp:</code>.<p>
208: *
209: * @param uri the URI to test
210: *
211: * @return <code>true</code> if the given URI starts with a scheme component
212: */
213: public static boolean hasScheme(String uri) {
214:
215: int pos = uri.indexOf(':');
216: // don't want to be misguided by a potential ':' in the query section of the URI (is this possible / allowed?)
217: // so consider only a ':' in the first 10 chars as a scheme
218: return (pos > -1) && (pos < 10);
219: }
220:
221: /**
222: * Returns <code>true</code> in case the given URI is absolute.<p>
223: *
224: * An URI is considered absolute if one of the following is true:<ul>
225: * <li>The URI starts with a <code>'/'</code> char.
226: * <li>The URI contains a <code>':'</code> in the first 10 chars.
227: * <li>The URI is <code>null</code>
228: * </ul>
229: *
230: * @param uri the URI to test
231: *
232: * @return <code>true</code> in case the given URI is absolute
233: */
234: public static boolean isAbsoluteUri(String uri) {
235:
236: return (uri == null)
237: || ((uri.length() >= 1) && ((uri.charAt(0) == '/') || hasScheme(uri)));
238: }
239:
240: /**
241: * Returns the online link for the given resource, with full server prefix.<p>
242: *
243: * Like <code>http://site.enterprise.com:8080/index.html</code>.<p>
244: *
245: * In case the resource name is a full root path, the site from the root path will be used.
246: * Otherwise the resource is assumed to be in the current site set be the OpenCms user context.<p>
247: *
248: * Please note that this method will always return the link as it will appear in the "Online"
249: * project, that is after the resource has been published. In case you need a method that
250: * just returns the link with the full server prefix, use {@link #getServerLink(CmsObject, String)}.<p>
251: *
252: * @param cms the current OpenCms user context
253: * @param resourceName the resource to generate the online link for
254: *
255: * @return the online link for the given resource, with full server prefix
256: *
257: * @see #getServerLink(CmsObject, String)
258: */
259: public String getOnlineLink(CmsObject cms, String resourceName) {
260:
261: String result = "";
262: try {
263: CmsProject currentProject = cms.getRequestContext()
264: .currentProject();
265: try {
266: cms.getRequestContext().setCurrentProject(
267: cms.readProject(CmsProject.ONLINE_PROJECT_ID));
268: result = substituteLinkForUnknownTarget(cms,
269: resourceName);
270: } finally {
271: cms.getRequestContext().setCurrentProject(
272: currentProject);
273: }
274: result = appendServerPrefix(cms, result);
275: } catch (CmsException e) {
276: // should never happen
277: result = e.getLocalizedMessage();
278: if (LOG.isErrorEnabled()) {
279: LOG.error(e.getLocalizedMessage(), e);
280: }
281: }
282: return result;
283: }
284:
285: /**
286: * Returns the perma link for the given resource.<p>
287: *
288: * Like
289: * <code>http://site.enterprise.com:8080/permalink/4b65369f-1266-11db-8360-bf0f6fbae1f8.html</code>.<p>
290: *
291: * @param cms the cms context
292: * @param resourceName the resource to generate the perma link for
293: *
294: * @return the perma link
295: */
296: public String getPermalink(CmsObject cms, String resourceName) {
297:
298: String permalink = "";
299: try {
300: permalink = substituteLink(cms,
301: CmsPermalinkResourceHandler.PERMALINK_HANDLER);
302: String id = cms.readResource(resourceName,
303: CmsResourceFilter.ALL).getStructureId().toString();
304: permalink += id;
305: String ext = CmsFileUtil.getExtension(resourceName);
306: if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(ext)) {
307: permalink += ext;
308: }
309: String serverPrefix = OpenCms.getSiteManager()
310: .getCurrentSite(cms).getServerPrefix(cms,
311: resourceName);
312: if (!permalink.startsWith(serverPrefix)) {
313: permalink = serverPrefix + permalink;
314: }
315: } catch (CmsException e) {
316: // if something wrong
317: permalink = e.getLocalizedMessage();
318: if (LOG.isErrorEnabled()) {
319: LOG.error(e.getLocalizedMessage(), e);
320: }
321: }
322: return permalink;
323: }
324:
325: /**
326: * Returns the result of the last extern link validation.<p>
327: *
328: * @return the result of the last extern link validation
329: */
330: public CmsExternalLinksValidationResult getPointerLinkValidationResult() {
331:
332: return m_pointerLinkValidationResult;
333: }
334:
335: /**
336: * Returns the resource root path in the OpenCms VFS for the given target URI link, or <code>null</code> in
337: * case the link points to an external site.<p>
338: *
339: * This methods does not support relative target URI links, so the given URI must be an absolute link.<p>
340: *
341: * See {@link #getRootPath(CmsObject, String)} for a full explanation of this method.<p>
342: *
343: * @param cms the current users OpenCms context
344: * @param targetUri the target URI link
345: *
346: * @return the resource root path in the OpenCms VFS for the given target URI link, or <code>null</code> in
347: * case the link points to an external site
348: *
349: * @see #getRootPath(CmsObject, String, String)
350: *
351: * @since 7.0.2
352: */
353: public String getRootPath(CmsObject cms, String targetUri) {
354:
355: return getRootPath(cms, targetUri, null);
356: }
357:
358: /**
359: * Returns the resource root path in the OpenCms VFS for the given target URI link, or <code>null</code> in
360: * case the link points to an external site.<p>
361: *
362: * The default implementation applies the following transformations to the link:<ul>
363: * <li>In case the link starts with a VFS prefix (for example <code>/opencms/opencms</code>,
364: * this prefix is removed from the result
365: * <li>In case the link is not a root path, the current site root is appended to the result.<p>
366: * <li>In case the link is relative, it will be made absolute using the given absolute <code>basePath</code>
367: * as starting point.<p>
368: * <li>In case the link contains a server schema (for example <code>http://www.mysite.de/</code>),
369: * which points to a configured site in OpenCms, the server schema is replaced with
370: * the root path of the site.<p>
371: * <li>In case the link points to an external site, or in case it is not a valid URI,
372: * then <code>null</code> is returned.<p>
373: * </ul>
374: *
375: * Please note the above text describes the default behavior as implemented by
376: * {@link CmsDefaultLinkSubstitutionHandler}, which can be fully customized using
377: * the {@link I_CmsLinkSubstitutionHandler} interface.<p>
378: *
379: * @param cms the current users OpenCms context
380: * @param targetUri the target URI link
381: * @param basePath path to use as base in case the target URI is relative (can be <code>null</code>)
382: *
383: * @return the resource root path in the OpenCms VFS for the given target URI link, or <code>null</code> in
384: * case the link points to an external site
385: *
386: * @see I_CmsLinkSubstitutionHandler for the interface that can be used to fully customize the link substitution
387: * @see CmsDefaultLinkSubstitutionHandler for the default link substitution handler
388: *
389: * @since 7.0.2
390: */
391: public String getRootPath(CmsObject cms, String targetUri,
392: String basePath) {
393:
394: return m_linkSubstitutionHandler.getRootPath(cms, targetUri,
395: basePath);
396: }
397:
398: /**
399: * Returns the link for the given resource in the current project, with full server prefix.<p>
400: *
401: * Like <code>http://site.enterprise.com:8080/index.html</code>.<p>
402: *
403: * In case the resource name is a full root path, the site from the root path will be used.
404: * Otherwise the resource is assumed to be in the current site set be the OpenCms user context.<p>
405: *
406: * @param cms the current OpenCms user context
407: * @param resourceName the resource to generate the online link for
408: *
409: * @return the link for the given resource in the current project, with full server prefix
410: *
411: * @see #getOnlineLink(CmsObject, String)
412: */
413: public String getServerLink(CmsObject cms, String resourceName) {
414:
415: String result = substituteLinkForUnknownTarget(cms,
416: resourceName);
417: return appendServerPrefix(cms, result);
418: }
419:
420: /**
421: * Sets the internal link substitution handler.<p>
422: *
423: * @param cms an OpenCms user context that must have the permissions for role {@link CmsRole#ROOT_ADMIN}.<p>
424: * @param linkSubstitutionHandler the handler to set
425: *
426: * @throws CmsRoleViolationException in case the provided OpenCms user context does not have the required permissions
427: */
428: public void setLinkSubstitutionHandler(CmsObject cms,
429: I_CmsLinkSubstitutionHandler linkSubstitutionHandler)
430: throws CmsRoleViolationException {
431:
432: OpenCms.getRoleManager().checkRole(cms, CmsRole.ROOT_ADMIN);
433: m_linkSubstitutionHandler = linkSubstitutionHandler;
434: }
435:
436: /**
437: * Sets the result of an external link validation.<p>
438: *
439: * @param externLinkValidationResult the result an external link validation
440: */
441: public void setPointerLinkValidationResult(
442: CmsExternalLinksValidationResult externLinkValidationResult) {
443:
444: m_pointerLinkValidationResult = externLinkValidationResult;
445: }
446:
447: /**
448: * Returns a link <i>from</i> the URI stored in the provided OpenCms user context
449: * <i>to</i> the given VFS resource, for use on web pages.<p>
450: *
451: * The result will contain the configured context path and
452: * servlet name, and in the case of the "online" project it will also be rewritten according to
453: * to the configured static export settings.<p>
454: *
455: * Should the current site of the given OpenCms user context <code>cms</code> be different from the
456: * site root of the given resource, the result will contain the full server URL to the target resource.<p>
457: *
458: * Please note the above text describes the default behavior as implemented by
459: * {@link CmsDefaultLinkSubstitutionHandler}, which can be fully customized using the
460: * {@link I_CmsLinkSubstitutionHandler} interface.<p>
461: *
462: * @param cms the current OpenCms user context
463: * @param resource the VFS resource the link should point to
464: *
465: * @return a link <i>from</i> the URI stored in the provided OpenCms user context
466: * <i>to</i> the given VFS resource, for use on web pages
467: */
468: public String substituteLink(CmsObject cms, CmsResource resource) {
469:
470: return substituteLinkForRootPath(cms, resource.getRootPath());
471: }
472:
473: /**
474: * Returns a link <i>from</i> the URI stored in the provided OpenCms user context
475: * <i>to</i> the VFS resource indicated by the given <code>link</code> in the current site,
476: * for use on web pages.<p>
477: *
478: * The provided <code>link</code> is assumed to be the contained in the site currently
479: * set in the provided OpenCms user context <code>cms</code>.<p>
480: *
481: * The result will be an absolute link that contains the configured context path and
482: * servlet name, and in the case of the "online" project it will also be rewritten according to
483: * to the configured static export settings.<p>
484: *
485: * In case <code>link</code> is a relative URI, the current URI contained in the provided
486: * OpenCms user context <code>cms</code> is used to make the relative <code>link</code> absolute.<p>
487: *
488: * Please note the above text describes the default behavior as implemented by
489: * {@link CmsDefaultLinkSubstitutionHandler}, which can be fully customized using the
490: * {@link I_CmsLinkSubstitutionHandler} interface.<p>
491: *
492: * @param cms the current OpenCms user context
493: * @param link the link to process which is assumed to point to a VFS resource, with optional parameters
494:
495: * @return a link <i>from</i> the URI stored in the provided OpenCms user context
496: * <i>to</i> the VFS resource indicated by the given <code>link</code> in the current site
497: */
498: public String substituteLink(CmsObject cms, String link) {
499:
500: return substituteLink(cms, link, null, false);
501: }
502:
503: /**
504: * Returns a link <i>from</i> the URI stored in the provided OpenCms user context
505: * <i>to</i> the VFS resource indicated by the given <code>link</code> and <code>siteRoot</code>,
506: * for use on web pages.<p>
507: *
508: * The result will be an absolute link that contains the configured context path and
509: * servlet name, and in the case of the "online" project it will also be rewritten according to
510: * to the configured static export settings.<p>
511: *
512: * In case <code>link</code> is a relative URI, the current URI contained in the provided
513: * OpenCms user context <code>cms</code> is used to make the relative <code>link</code> absolute.<p>
514: *
515: * The provided <code>siteRoot</code> is assumed to be the "home" of the link.
516: * In case the current site of the given OpenCms user context <code>cms</code> is different from the
517: * provided <code>siteRoot</code>, the full server prefix is appended to the result link.<p>
518: *
519: * Please note the above text describes the default behavior as implemented by
520: * {@link CmsDefaultLinkSubstitutionHandler}, which can be fully customized using the
521: * {@link I_CmsLinkSubstitutionHandler} interface.<p>
522: *
523: * @param cms the current OpenCms user context
524: * @param link the link to process which is assumed to point to a VFS resource, with optional parameters
525: * @param siteRoot the site root of the <code>link</code>
526: *
527: * @return the substituted link
528: */
529: public String substituteLink(CmsObject cms, String link,
530: String siteRoot) {
531:
532: return substituteLink(cms, link, siteRoot, false);
533: }
534:
535: /**
536: * Returns a link <i>from</i> the URI stored in the provided OpenCms user context
537: * <i>to</i> the VFS resource indicated by the given <code>link</code> and <code>siteRoot</code>,
538: * for use on web pages, using the configured link substitution handler.<p>
539: *
540: * The result will be an absolute link that contains the configured context path and
541: * servlet name, and in the case of the "online" project it will also be rewritten according to
542: * to the configured static export settings.<p>
543: *
544: * In case <code>link</code> is a relative URI, the current URI contained in the provided
545: * OpenCms user context <code>cms</code> is used to make the relative <code>link</code> absolute.<p>
546: *
547: * The provided <code>siteRoot</code> is assumed to be the "home" of the link.
548: * In case the current site of the given OpenCms user context <code>cms</code> is different from the
549: * provided <code>siteRoot</code>, the full server prefix is appended to the result link.<p>
550: *
551: * A server prefix is also added if
552: * <ul>
553: * <li>the link is contained in a normal document and the link references a secure document</li>
554: * <li>the link is contained in a secure document and the link references a normal document</li>
555: * </ul>
556: *
557: * Please note the above text describes the default behavior as implemented by
558: * {@link CmsDefaultLinkSubstitutionHandler}, which can be fully customized using the
559: * {@link I_CmsLinkSubstitutionHandler} interface.<p>
560: *
561: * @param cms the current OpenCms user context
562: * @param link the link to process which is assumed to point to a VFS resource, with optional parameters
563: * @param siteRoot the site root of the <code>link</code>
564: * @param forceSecure if <code>true</code> generates always an absolute URL (with protocol and server name) for secure links
565: *
566: * @return a link <i>from</i> the URI stored in the provided OpenCms user context
567: * <i>to</i> the VFS resource indicated by the given <code>link</code> and <code>siteRoot</code>
568: *
569: * @see I_CmsLinkSubstitutionHandler for the interface that can be used to fully customize the link substitution
570: * @see CmsDefaultLinkSubstitutionHandler for the default link substitution handler
571: */
572: public String substituteLink(CmsObject cms, String link,
573: String siteRoot, boolean forceSecure) {
574:
575: return m_linkSubstitutionHandler.getLink(cms, link, siteRoot,
576: forceSecure);
577: }
578:
579: /**
580: * Returns a link <i>from</i> the URI stored in the provided OpenCms user context
581: * <i>to</i> the VFS resource indicated by the given root path, for use on web pages.<p>
582: *
583: * The result will contain the configured context path and
584: * servlet name, and in the case of the "online" project it will also be rewritten according to
585: * to the configured static export settings.<p>
586: *
587: * Should the current site of the given OpenCms user context <code>cms</code> be different from the
588: * site root of the given resource root path, the result will contain the full server URL to the target resource.<p>
589: *
590: * @param cms the current OpenCms user context
591: * @param rootPath the VFS resource root path the link should point to
592: *
593: * @return a link <i>from</i> the URI stored in the provided OpenCms user context
594: * <i>to</i> the VFS resource indicated by the given root path
595: */
596: public String substituteLinkForRootPath(CmsObject cms,
597: String rootPath) {
598:
599: String siteRoot = OpenCms.getSiteManager()
600: .getSiteRoot(rootPath);
601: if (siteRoot == null) {
602: // use current site root in case no valid site root is available
603: // this will also be the case if a "/system" link is used
604: siteRoot = cms.getRequestContext().getSiteRoot();
605: }
606: String sitePath;
607: if (rootPath.startsWith(siteRoot)) {
608: // only cut the site root if the root part really has this prefix
609: sitePath = rootPath.substring(siteRoot.length());
610: } else {
611: sitePath = rootPath;
612: }
613: return substituteLink(cms, sitePath, siteRoot, false);
614: }
615:
616: /**
617: * Returns a link <i>from</i> the URI stored in the provided OpenCms user context
618: * <i>to</i> the given <code>link</code>, for use on web pages.<p>
619: *
620: * A number of tests are performed with the <code>link</code> in order to find out how to create the link:<ul>
621: * <li>If <code>link</code> is empty, an empty String is returned.
622: * <li>If <code>link</code> starts with an URI scheme component, for example <code>http://</code>,
623: * and does not point to an internal OpenCms site, it is returned unchanged.
624: * <li>If <code>link</code> is an absolute URI that starts with a configured site root,
625: * the site root is cut from the link and
626: * the same result as {@link #substituteLink(CmsObject, String, String)} is returned.
627: * <li>Otherwise the same result as {@link #substituteLink(CmsObject, String)} is returned.
628: * </ul>
629: *
630: * @param cms the current OpenCms user context
631: * @param link the link to process
632: *
633: * @return a link <i>from</i> the URI stored in the provided OpenCms user context
634: * <i>to</i> the given <code>link</code>
635: */
636: public String substituteLinkForUnknownTarget(CmsObject cms,
637: String link) {
638:
639: if (CmsStringUtil.isEmpty(link)) {
640: return "";
641: }
642: String sitePath = link;
643: String siteRoot = null;
644: if (hasScheme(link)) {
645: // the link has a scheme, that is starts with something like "http://"
646: // usually this should be a link to an external resource, but check anyway
647: sitePath = getRootPath(cms, link);
648: if (sitePath == null) {
649: // probably an external link, don't touch this
650: return link;
651: }
652: }
653: // check if we can find a site from the link
654: siteRoot = OpenCms.getSiteManager().getSiteRoot(sitePath);
655: if (siteRoot == null) {
656: // use current site root in case no valid site root is available
657: // this will also be the case if a "/system" link is used
658: siteRoot = cms.getRequestContext().getSiteRoot();
659: } else {
660: // we found a site root, cut this from the resource path
661: sitePath = link.substring(siteRoot.length());
662: }
663: return substituteLink(cms, sitePath, siteRoot, false);
664: }
665:
666: /**
667: * Returns the link for the given resource in the current project, with full server prefix.<p>
668: *
669: * The input link must already have been processed according to the link substitution rules.
670: * This method does just append the server prefix in case this is requires.<p>
671: *
672: * @param cms the current OpenCms user context
673: * @param link the resource to generate the online link for
674: *
675: * @return the link for the given resource in the current project, with full server prefix
676: */
677: private String appendServerPrefix(CmsObject cms, String link) {
678:
679: if (isAbsoluteUri(link) && !hasScheme(link)) {
680: // URI is absolute and contains no schema
681: // this indicates source and target link are in the same site
682: String serverPrefix;
683: if (cms.getRequestContext().currentProject()
684: .isOnlineProject()) {
685: // on online project, get the real site name from the site manager
686: CmsSite currentSite = OpenCms.getSiteManager().getSite(
687: link, cms.getRequestContext().getSiteRoot());
688: serverPrefix = currentSite.getServerPrefix(cms, link);
689: } else {
690: // in offline mode, source must be the workplace
691: // so append the workplace server so links can still be clicked
692: serverPrefix = OpenCms.getSiteManager()
693: .getWorkplaceServer();
694: }
695: link = serverPrefix + link;
696: }
697: return link;
698: }
699: }
|