Skip to content

Commit

Permalink
Implemented EL wrapper for links.
Browse files Browse the repository at this point in the history
  • Loading branch information
gWestenberger committed Jun 1, 2023
1 parent 3b1bb0a commit bac409f
Show file tree
Hide file tree
Showing 4 changed files with 344 additions and 61 deletions.
68 changes: 42 additions & 26 deletions src/org/opencms/jsp/CmsJspTagLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.opencms.file.CmsVfsResourceNotFoundException;
import org.opencms.flex.CmsFlexController;
import org.opencms.i18n.CmsLocaleManager;
import org.opencms.jsp.util.CmsLinkWrapper;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
Expand Down Expand Up @@ -308,27 +309,7 @@ public static String linkTagAction(Parameters params, ServletRequest req) {
CmsFlexController controller = CmsFlexController.getController(req);
// be sure the link is absolute
String uri = CmsLinkManager.getAbsoluteUri(params.getTarget(), controller.getCurrentRequest().getElementUri());
CmsObject cms = controller.getCmsObject();
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.getBaseUri()) || (null != params.getLocale())) {
try {
cms = OpenCms.initCmsObject(cms);
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.getBaseUri())) {
cms.getRequestContext().setUri(params.getBaseUri());
if (params.getLocale() == null) {
Locale baseUriLocale = getBaseUriLocale(cms, params.getBaseUri());
if (baseUriLocale != null) {
cms.getRequestContext().setLocale(baseUriLocale);
}
}
}
if (null != params.getLocale()) {
cms.getRequestContext().setLocale(params.getLocale());
}
} catch (CmsException e) {
// should not happen, if it does we can't do anything useful and will just keep the original object
LOG.debug(e.getLocalizedMessage(), e);
}
}
CmsObject cms = prepareCmsObject(controller.getCmsObject(), params);
CmsLinkManager linkManager = OpenCms.getLinkManager();
// generate the link
switch (params.getType()) {
Expand Down Expand Up @@ -464,6 +445,39 @@ public static String linkTagAction(
return linkTagAction(new Parameters(target, baseUri, detailPage, locale, Type.DEFAULT), req);
}

/**
* Initializes CmsObject with data from the tag parameters.
*
* @param cms1 the CmsObject to use as a base
* @param params the parameters to use for the initialization
* @return the initialized CmsObject
*/
private static CmsObject prepareCmsObject(CmsObject cms1, Parameters params) {

CmsObject cms = cms1;
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.getBaseUri()) || (null != params.getLocale())) {
try {
cms = OpenCms.initCmsObject(cms);
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(params.getBaseUri())) {
cms.getRequestContext().setUri(params.getBaseUri());
if (params.getLocale() == null) {
Locale baseUriLocale = getBaseUriLocale(cms, params.getBaseUri());
if (baseUriLocale != null) {
cms.getRequestContext().setLocale(baseUriLocale);
}
}
}
if (null != params.getLocale()) {
cms.getRequestContext().setLocale(params.getLocale());
}
} catch (CmsException e) {
// should not happen, if it does we can't do anything useful and will just keep the original object
LOG.debug(e.getLocalizedMessage(), e);
}
}
return cms;
}

/**
* @see javax.servlet.jsp.tagext.Tag#doEndTag()
*
Expand All @@ -479,13 +493,11 @@ public int doEndTag() throws JspException {
// This will always be true if the page is called through OpenCms
if (CmsFlexController.isCmsRequest(req)) {
try {

// Get link-string from the body and reset body
String link = getBodyContent().getString();
getBodyContent().clear();
// Calculate the link substitution
String newlink = linkTagAction(
new Parameters(link, getBaseUri(), getDetailPage(), m_locale, m_type),
req);
Parameters params = new Parameters(link, getBaseUri(), getDetailPage(), m_locale, m_type);
if (m_var != null) {
int scope = PageContext.PAGE_SCOPE; // default
if (SCOPE_REQUEST.equalsIgnoreCase(m_scope)) {
Expand All @@ -495,8 +507,12 @@ public int doEndTag() throws JspException {
} else if (SCOPE_APPLICATION.equalsIgnoreCase(m_scope)) {
scope = PageContext.APPLICATION_SCOPE;
}
pageContext.setAttribute(m_var, newlink, scope);
CmsFlexController controller = CmsFlexController.getController(req);
CmsObject cms = prepareCmsObject(controller.getCmsObject(), params);
pageContext.setAttribute(m_var, new CmsLinkWrapper(cms, link), scope);
} else {
// Calculate the link substitution
String newlink = linkTagAction(params, req);
// Write the result back to the page
getBodyContent().print(newlink);
getBodyContent().writeOut(pageContext.getOut());
Expand Down
24 changes: 23 additions & 1 deletion src/org/opencms/jsp/util/A_CmsJspValueWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;

import org.apache.commons.collections.Transformer;
import org.apache.commons.logging.Log;
Expand Down Expand Up @@ -167,6 +168,9 @@ public Object transform(Object input) {
/** The lazy initialized trim to size map. */
private Map<Object, String> m_trimToSize;

/** Cached link wrapper - use Optional to distinguish 'uncached' state from 'does not exist'. */
protected Optional<CmsLinkWrapper> m_linkObj;

/**
* Returns the substituted link to the given target.<p>
*
Expand Down Expand Up @@ -504,14 +508,32 @@ public Long getToInteger() {
return getToLong();
}

/**
* Converts the value to a link wrapper.
*
* @return the link wrapper
*/
public CmsLinkWrapper getToLink() {

if (m_linkObj == null) {
String target = toString();
if (target != null) {
m_linkObj = Optional.of(new CmsLinkWrapper(m_cms, target));
} else {
m_linkObj = Optional.empty();
}
}
return m_linkObj.orElse(null);
}

/**
* Returns the substituted link to the wrapped value.<p>
*
* In case no link can be substituted from the wrapped value, an empty String <code>""</code> is returned.
*
* @return the substituted link
*/
public String getToLink() {
public String getToLinkStr() {

if (m_link == null) {
String target = toString();
Expand Down
232 changes: 232 additions & 0 deletions src/org/opencms/jsp/util/CmsLinkWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

package org.opencms.jsp.util;

import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.jsp.CmsJspResourceWrapper;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.relations.CmsLink;
import org.opencms.relations.CmsRelationType;
import org.opencms.util.CmsStringUtil;
import org.opencms.xml.types.CmsXmlVarLinkValue;

import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;

/**
* Wrapper for handling links in template/formatter JSP EL.
*/
public class CmsLinkWrapper extends A_CmsJspValueWrapper {

/** Logger instance for this class. */
private static final Log LOG = CmsLog.getLog(CmsLinkWrapper.class);

/** Stored CMS context. */
protected CmsObject m_cms;

/** The link literal from which this wrapper was created. */
protected String m_link;

/** Cached internal/external state. */
protected Boolean m_internal;

/** Cached link target resource. */
protected Optional<CmsResource> m_resource;

/** Cached links (online, perma, server). */
protected Map<String, String> m_stringCache = new ConcurrentHashMap<>();

/**
* Creates a new link wrapper.
*
* <p>The link parameter should be in the same format that you enter in an XML content of field of type OpenCmsVarLink, i.e.
* either a full external URL or a site path with a query string attached.
*
* @param cms the CMS context
* @param link the link to wrap
*/
public CmsLinkWrapper(CmsObject cms, String link) {

m_cms = cms;
m_link = link;
}

/**
* @see org.opencms.jsp.util.A_CmsJspValueWrapper#getExists()
*/
@Override
public boolean getExists() {

return m_link != null;
}

/**
* @see org.opencms.jsp.util.A_CmsJspValueWrapper#getIsEmpty()
*/
@Override
public boolean getIsEmpty() {

return CmsStringUtil.isEmpty(m_link);
}

/**
* @see org.opencms.jsp.util.A_CmsJspValueWrapper#getIsEmptyOrWhitespaceOnly()
*/
@Override
public boolean getIsEmptyOrWhitespaceOnly() {

return CmsStringUtil.isEmptyOrWhitespaceOnly(m_link);
}

/**
* Returns true if the link is internal.
*
* @return true if the link is internal
*/
public boolean getIsInternal() {

if (m_internal == null) {
m_internal = Boolean.valueOf(null != CmsXmlVarLinkValue.getInternalPathAndQuery(m_cms, m_link));
}
return m_internal.booleanValue();
}

/**
* Performs normal link substitution.
*
* @return the substituted link
*/
public String getLink() {

return m_stringCache.computeIfAbsent("link", k -> substituteLink(m_cms, m_link));
}

/**
* Gets the literal from which this wrapper was constructed.
*
* @return the original link literal
*/
public String getLiteral() {

return m_link;
}

/**
* @see org.opencms.jsp.util.A_CmsJspValueWrapper#getObjectValue()
*/
@Override
public Object getObjectValue() {

return m_link;
}

/**
* Performs online link substitution.
*
* @return the online link
*/
public String getOnlineLink() {

return m_stringCache.computeIfAbsent("online", k -> OpenCms.getLinkManager().getOnlineLink(m_cms, m_link));
}

/**
* Performs permalink substitution.
*
* @return the permalink
*/
public String getPermaLink() {

return m_stringCache.computeIfAbsent("perma", k -> OpenCms.getLinkManager().getPermalink(m_cms, m_link));
}

/**
* Gets the resource wrapper for the link target.
*
* @return the resource wrapper for the target
*/
public CmsJspResourceWrapper getResource() {

if (m_resource == null) {
try {
String link = CmsXmlVarLinkValue.getInternalPathAndQuery(m_cms, m_link);
if (link == null) {
m_resource = Optional.empty();
} else {
CmsLink linkObj = new CmsLink(/*name=*/null, CmsRelationType.HYPERLINK, link, true);
linkObj.checkConsistency(m_cms);
m_resource = Optional.ofNullable(linkObj.getResource());
}
} catch (Exception e) {
LOG.warn(e.getLocalizedMessage(), e);
m_resource = Optional.empty();
}
}
if (m_resource.isPresent()) {
return CmsJspResourceWrapper.wrap(m_cms, m_resource.get());
} else {
return null;
}

}

/**
* Performs server link substitution.
*
* @return the server link
*/
public String getServerLink() {

return m_stringCache.computeIfAbsent("server", k -> OpenCms.getLinkManager().getServerLink(m_cms, m_link));
}

/**
* @see org.opencms.jsp.util.A_CmsJspValueWrapper#hashCode()
*/
@Override
public int hashCode() {

return Objects.hashCode(m_link);
}

/**
* @see java.util.AbstractCollection#toString()
*/
@Override
public String toString() {

return getLink();
}

}
Loading

0 comments on commit bac409f

Please sign in to comment.