/* * Copyright 2012 Oracle Corporation. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fatwire.gst.foundation.wra.navigation; import static com.fatwire.gst.foundation.facade.runtag.asset.FilterAssetsByDate.isValidOnDate; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.LinkedList; import java.util.List; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import COM.FutureTense.Interfaces.ICS; import COM.FutureTense.Interfaces.Utilities; import com.fatwire.assetapi.data.AssetId; import com.fatwire.cs.core.db.PreparedStmt; import com.fatwire.cs.core.db.StatementParam; import com.fatwire.gst.foundation.facade.assetapi.asset.TemplateAsset; import com.fatwire.gst.foundation.facade.assetapi.asset.TemplateAssetAccess; import com.fatwire.gst.foundation.facade.runtag.render.LogDep; import com.fatwire.gst.foundation.facade.sql.IListIterable; import com.fatwire.gst.foundation.facade.sql.Row; import com.fatwire.gst.foundation.facade.sql.SqlHelper; import com.fatwire.gst.foundation.facade.uri.TemplateUriBuilder; import com.fatwire.gst.foundation.wra.navigation.support.AbstractNavigationService; import com.fatwire.gst.foundation.wra.Alias; import com.fatwire.gst.foundation.wra.AliasCoreFieldDao; import com.fatwire.gst.foundation.wra.WraUriBuilder; import com.fatwire.mda.DimensionFilterInstance; /** * @author Dolf Dijkstra * * * @deprecated as of release 12.x, will be replaced with a brand new, significantly improved NavigationService implementation (coming soon) * */ public class WraNavigationService extends AbstractNavigationService implements NavigationService { private static final Logger LOG = LoggerFactory.getLogger("tools.gsf.legacy.wra.navigation.WraNavigationService"); /** * Name of the page subtype indicating that this page is NOT rendered on the * site but is instead merely used to group navigation components on the * site. */ public static final String NAVBAR_NAME = "GSTNavName"; /** * Name of the page subtype indicating that this page is a Link, meaning * that the content is in the unnamed association */ public static final String NAVBAR_LINK = "GSTNavLink"; /** * Constant containing the asset type of the GST Alias asset. */ public final String GST_ALIAS_TYPE = Alias.ALIAS_ASSET_TYPE_NAME; private static final String CHILD_SQL = "SELECT otype,oid,nrank,nid from SitePlanTree where nparentid=? and ncode='Placed' order by nrank"; private static final PreparedStmt CHILD_STMT = new PreparedStmt(CHILD_SQL, Arrays.asList("SitePlanTree")); static { CHILD_STMT.setElement(0, "SitePlanTree", "nparentid"); } /** * Local instance of the AliasCoreFieldDao. */ protected final AliasCoreFieldDao aliasDao; protected final DimensionFilterInstance dimensionFilter; private final Date date; public WraNavigationService(ICS ics, TemplateAssetAccess assetTemplate, AliasCoreFieldDao aliasDao, final DimensionFilterInstance dimensionFilter, Date previewDate) { super(ics, assetTemplate, "linktext", "path"); this.aliasDao = aliasDao; this.dimensionFilter = dimensionFilter; this.date = previewDate; } @Override protected NavigationNode getNode(Row row, int level, int depth, String linkAttribute) { long nid = row.getLong("nid"); long pageId = row.getLong("oid"); AssetId pid = assetTemplate.createAssetId(row.getString("otype"), pageId); if (!isValidOnDate(ics, pid, date)) { // the input object is not valid. Abort if (LOG.isDebugEnabled()) { LOG.debug("Input asset " + pid + " is not effective."); } return null; } LogDep.logDep(ics, pid); // probably redundant call TemplateAsset asset = assetTemplate.read(pid, "name", "subtype", "template", pathAttribute, linkAttribute); final NavigationNode node = new NavigationNode(); node.setPage(pid); node.setLevel(level); node.setPagesubtype(asset.getSubtype()); node.setPagename(asset.asString("name")); final boolean isNavigationPlaceholder = NAVBAR_NAME.equals(asset.asString("subtype")); final boolean isNavigationLink = NAVBAR_LINK.equals(asset.asString("subtype")); if (isNavigationPlaceholder) { // return node without an associated asset } else if (isNavigationLink) { Collection<AssetId> assocs; assocs = assetTemplate.readAssociatedAssetIds(pid, "-"); if (dimensionFilter != null) assocs = dimensionFilter.filterAssets(assocs); for (AssetId assoc : assocs) { if (isValidOnDate(ics, assoc, date)) { if (isGstAlias(assoc)) { final Alias alias = aliasDao.getAlias(assoc); node.setId(alias.getId()); final String url = alias.getTargetUrl() != null ? alias.getTargetUrl() : getUrl(alias .getTarget()); final String linktext = alias.getLinkText(); if (url != null) { node.setUrl(url); } if (linktext != null) { node.setLinktext(linktext); } } else { node.setId(assoc); asset = assetTemplate.read(assoc, "name", "subtype", "template", pathAttribute, linkAttribute); final String url = getUrl(asset); if (url != null) { node.setUrl(url); // escape by default. } final String linktext = asset.asString(linkAttribute); if (linktext != null) { node.setLinktext(linktext); } else { node.setLinktext(asset.asString("name")); } } } } } else { // TODO Add support for locale (date checking is already done at // start of this function). // other subtype final String url = getUrl(asset); if (url != null) { node.setUrl(url); // escape by default. } final String linktext = asset.asString(linkAttribute); if (linktext != null) { node.setLinktext(linktext); } else { node.setLinktext(asset.asString("name")); } } if (depth < 0 || depth > level) { // get the children in the Site Plan, note recursing here Collection<NavigationNode> children = getNodeChildren(nid, level + 1, depth, linkAttribute); for (final NavigationNode kid : children) { if (kid != null && kid.getPage() != null) { node.addChild(kid); } } } return node; } private String getUrl(AssetId assoc) { TemplateAsset asset = assetTemplate.read(assoc, "name", "subtype", "template", pathAttribute); return getUrl(asset); } @Override protected Collection<NavigationNode> getNodeChildren(final long nodeId, final int level, final int depth, String linkAttribute) { StatementParam param = CHILD_STMT.newParam(); param.setLong(0, nodeId); IListIterable root = SqlHelper.select(ics, CHILD_STMT, param); List<NavigationNode> collection = new LinkedList<NavigationNode>(); for (Row row : root) { final NavigationNode node = getNode(row, level, depth, linkAttribute); if (node != null) collection.add(node); } return collection; } /** * Builds up a URI for this asset, using the pathAttribute and the template * field of the asset * * @param asset template asset * @return the uri, xml escaped */ protected String getUrl(TemplateAsset asset) { String template = asset.asString("template"); String path = asset.asString(pathAttribute); if (StringUtils.isBlank(template)) { LOG.debug("Asset " + asset.getAssetId() + " does not have a valid template set."); return null; } if (StringUtils.isBlank(path)) { LOG.debug("Asset " + asset.getAssetId() + " does not have a valid path set. Defaulting to a non Vanity Url."); return new TemplateUriBuilder(asset.getAssetId(), template).toURI(ics); } String wrapper = ics.GetProperty("com.fatwire.gst.foundation.url.wrapathassembler.dispatcher", "ServletRequest.properties", true); if (!Utilities.goodString(wrapper)) { wrapper = "GST/Dispatcher"; } String uri = new WraUriBuilder(asset.getAssetId()).wrapper(wrapper).template(template).toURI(ics); return StringEscapeUtils.escapeXml(uri); } /** * Return true if the asset type is a GSTAlias asset type. May be overridden * if customers are attempting to retrofit this class for alias-like * functionality that is not implemented by the GSTAlias asset type. * * @param id asset for which a link is required * @return true if the asset is an alias, false if it is a web-referenceable * asset */ protected boolean isGstAlias(final AssetId id) { return GST_ALIAS_TYPE.equals(id.getType()); } }