Package com.cognifide.slice.cq.taglib.include

Source Code of com.cognifide.slice.cq.taglib.include.IncludeTag

package com.cognifide.slice.cq.taglib.include;

/*-
* #%L
* Slice - CQ Taglib
* $Id:$
* $HeadURL:$
* %%
* Copyright (C) 2012 Cognifide Limited
* %%
* 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.
* #L%
*/

import java.util.Arrays;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;

import com.cognifide.slice.cq.taglib.AbstractBodyTag;
import com.day.cq.wcm.api.WCMMode;
import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.components.ComponentManager;
import com.day.cq.wcm.api.components.IncludeOptions;

/**
* Extended version of the cq:include tag. In addition to the original behaviour allows controlling the WCM
* mode inside the include, and disabling the decoration markup that's added by WCM by default. The control is
* done either at component level - using custom properties stored in a component's node, or at the include
* level - using tag's attributes. Tag's attributes have higher priority than component's meta-data.
*
* @author Jan Kuźniak
* @author Witold Szczerba
* @author maciej.majchrzak
*/
public class IncludeTag extends AbstractBodyTag {

  private static final long serialVersionUID = -214258163075048064L;

  static final DecorationMode DEFAULT_DECORATION_MODE = DecorationMode.ALL;

  static final boolean DEFAULT_DISABLE_WCM = false;

  private Boolean disableWcm;

  private Boolean enableDecoration;

  private String[] additionalCssClassNames;

  /**
   * The path to the resource object to include in the current request processing. If this path is relative
   * it is appended to the path of the current resource whose script is including the given resource. Either
   * resource or path must be specified. If both are specified, the resource takes precedences.
   */
  private String path;

  /**
   * The resource type of a resource to include. If the resource to be included is specified with the path
   * attribute, which cannot be resolved to a resource, the tag may create a synthetic resource object out
   * of the path and this resource type. If the resource type is set the path must be the exact path to a
   * resource object. That is, adding parameters, selectors and extensions to the path is not supported if
   * the resource type is set.
   */
  private String resourceType;

  /** wrapping the original include tag to mimic it's behaviour */
  private com.day.cq.wcm.tags.IncludeTag wcmIncludeTag = new com.day.cq.wcm.tags.IncludeTag();

  /** {@inheritDoc} */
  @Override
  public int doStartTag() throws JspException {
    return wcmIncludeTag.doStartTag();
  }

  /** @param disableWcm the disableWcm to set */
  public void setDisableWcm(boolean disableWcm) {
    this.disableWcm = disableWcm;
  }

  /** @param enableDecoration the enableDecoration to set */
  public void setEnableDecoration(boolean enableDecoration) {
    this.enableDecoration = enableDecoration;
  }

  /** @param flush the flush to set */
  public void setFlush(Boolean flush) {
    this.wcmIncludeTag.setFlush(flush);
  }

  /** @param path the path to set */
  public void setPath(String path) {
    this.path = path;
    wcmIncludeTag.setPath(path);
  }

  /** @param resourceType the resourceType to set */
  public void setResourceType(String resourceType) {
    this.resourceType = resourceType;
    wcmIncludeTag.setResourceType(resourceType);
  }

  /** @param script the script to set */
  public void setScript(String script) {
    wcmIncludeTag.setScript(script);
  }

  /** @param ignoreComponentHierarchy the ignoreComponentHierarchy to set */
  public void setIgnoreComponentHierarchy(boolean ignoreComponentHierarchy) {
    wcmIncludeTag.setIgnoreComponentHierarchy(ignoreComponentHierarchy);
  }

  public void setAdditionalCssClassNames(final String additionalCssClassNames) {
    this.additionalCssClassNames = StringUtils.split(additionalCssClassNames, ',');
  }

  /** {@inheritDoc} */
  @Override
  public void setPageContext(PageContext pageContext) {
    super.setPageContext(pageContext);
    wcmIncludeTag.setPageContext(pageContext);
  }

  /** {@inheritDoc} */
  @Override
  public void setParent(Tag t) {
    super.setParent(t);
    wcmIncludeTag.setParent(t);
  }

  /** {@inheritDoc} */
  @Override
  public void setId(String id) {
    super.setId(id);
    wcmIncludeTag.setId(id);
  }

  /** {@inheritDoc} */
  @Override
  public void release() {
    super.release();
    wcmIncludeTag.release();
  }

  /** {@inheritDoc} */
  @Override
  public void removeValue(String k) {
    super.removeValue(k);
    wcmIncludeTag.removeValue(k);
  }

  /** {@inheritDoc} */
  @Override
  public void setValue(String k, Object o) {
    super.setValue(k, o);
    wcmIncludeTag.setValue(k, o);
  }

  /** {@inheritDoc} */
  @Override
  public int doEndTag() throws JspException {
    // we consider removing decoration only if we're including a component
    SlingHttpServletRequest request = getRequest();
    WCMMode wcmMode = WCMMode.fromRequest(request);

    ComponentConfiguration componentConfiguration = readComponentConfiguration(request);

    boolean decorationEnabled;
    if (this.enableDecoration == null) {
      decorationEnabled = isDecorationEnabled(componentConfiguration.getDecorationModes(), wcmMode);
    } else {
      decorationEnabled = this.enableDecoration;
    }

    IncludeOptions options = IncludeOptions.getOptions(request, true);
    if (!decorationEnabled) {
      options.forceSameContext(true);
      options.setDecorationTagName("");
    }

    boolean wcmDisabled;
    if (this.disableWcm == null) {
      wcmDisabled = componentConfiguration.isDisableWcm(); // default is in componentConfiguration
    } else {
      wcmDisabled = this.disableWcm;
    }

    if (wcmDisabled) {
      WCMMode.DISABLED.toRequest(request);
    }
    try {
      String[] componentAdditionalCssClassNames = componentConfiguration.getAdditionalCssClassNames();
      if ((null != componentAdditionalCssClassNames) && (componentAdditionalCssClassNames.length > 0)) {
        options.getCssClassNames().addAll(Arrays.asList(componentAdditionalCssClassNames));
      }

      if ((null != additionalCssClassNames) && (additionalCssClassNames.length > 0)) {
        options.getCssClassNames().addAll(Arrays.asList(additionalCssClassNames));
      }

      wcmIncludeTag.setResourceType(resourceType);
      return wcmIncludeTag.doEndTag();
    } finally {
      if (wcmDisabled) {
        wcmMode.toRequest(request);
      }
    }
  }

  private ComponentConfiguration readComponentConfiguration(SlingHttpServletRequest request) {
    ComponentConfiguration componentConfiguration = new ComponentConfiguration(logger);

    if ((resourceType != null) && (path != null)) {
      ComponentManager componentManager = request.getResourceResolver().adaptTo(ComponentManager.class);
      if (componentManager != null) {
        Component component = componentManager.getComponent(resourceType);
        if (component != null) {
          componentConfiguration.readFromComponent(component);
        } else {
          logger.warn("Cannot read component configuration for '{}' at {}", resourceType, path);
        }
      } else {
        logger.warn("Unable to obtain component manager for '{}' at {}", resourceType, path);
      }
    }
    return componentConfiguration;
  }

  private boolean isDecorationEnabled(DecorationMode[] decorationModes, WCMMode wcmMode) {
    boolean enabled = false;
    for (int i = 0; (i < decorationModes.length) && !enabled; i++) {
      DecorationMode decorationMode = decorationModes[i];
      if (null != decorationMode) {
        enabled = decorationMode.isEnabledInWcmMode(wcmMode);
      }
    }
    return enabled;
  }

  // /////////////////////////////////////////////////////////////////////////
  // DecorationMode enum
  // ///////////////////////////////////////////////////////////////////////

  /**
   * Represents configuration options for the {{cog:enableDecorationInModes}} property.
   */
  enum DecorationMode {
    /** decoration is enabled in the WCM disabled mode */
    DISABLED("disabled"), //
    /** decoration is enabled in the WCM edit mode */
    EDIT("edit"), //
    /** decoration is enabled in the WCM read-only mode */
    READ_ONLY("read-only"), //
    /** decoration is enabled in the WCM preview-mode */
    PREVIEW("preview"), //
    /** decoration is enabled in the WCM design-mode */
    DESIGN("design"), //
    /** decoration is enabled in the authoring mode */
    AUTHOR("author"), //
    /** decoration is enabled in the publish mode */
    PUBLISH("publish"), //
    /** decoration is enabled in all WCM modes */
    ALL("all"), //
    /** decoration is disabled (not enabled in any mode) */
    NONE("none");

    private String name;

    private DecorationMode(String name) {
      this.name = name;
    }

    public static DecorationMode fromObject(Object o) {
      if (o == null) {
        return null;
      } else {
        return fromNotNullString(o.toString());
      }
    }

    public static DecorationMode fromString(String name) {
      if (name == null) {
        return null;
      } else {
        return fromNotNullString(name);
      }
    }

    private static DecorationMode fromNotNullString(String name) {
      for (DecorationMode b : DecorationMode.values()) {
        if (name.equals(b.name)) {
          return b;
        }
      }
      // default
      return null;
    }

    /**
     * Returns true if the decoration mode is enabled in the current WCM Mode
     *
     * @param wcmMode the WCM mode model representing current state of the WCM
     * @return true if the decoration mode is enabled in given WCM mode, false otherwise
     */
    public boolean isEnabledInWcmMode(WCMMode wcmMode) {
      boolean enabled = (this == DISABLED) && (wcmMode == WCMMode.DISABLED);
      enabled |= (this == EDIT) && (wcmMode == WCMMode.EDIT);
      enabled |= (this == READ_ONLY) && (wcmMode == WCMMode.READ_ONLY);
      enabled |= (this == PREVIEW) && (wcmMode == WCMMode.PREVIEW);
      enabled |= (this == DESIGN) && (wcmMode == WCMMode.DESIGN);
      enabled |= (this == AUTHOR) && ((wcmMode == WCMMode.EDIT) || (wcmMode == WCMMode.DESIGN));
      enabled |= (this == PUBLISH) && ((wcmMode != WCMMode.EDIT) && (wcmMode != WCMMode.DESIGN));
      enabled |= (this == ALL);
      return enabled;
    }
  }
}
TOP

Related Classes of com.cognifide.slice.cq.taglib.include.IncludeTag

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.