Package com.gentics.cr.plink

Source Code of com.gentics.cr.plink.LucenePathResolver

package com.gentics.cr.plink;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import com.gentics.api.lib.datasource.Datasource;
import com.gentics.api.lib.datasource.DatasourceException;
import com.gentics.api.lib.datasource.DatasourceNotAvailableException;
import com.gentics.api.lib.exception.ParserException;
import com.gentics.api.lib.expressionparser.Expression;
import com.gentics.api.lib.expressionparser.ExpressionParserException;
import com.gentics.api.lib.expressionparser.filtergenerator.DatasourceFilter;
import com.gentics.api.lib.resolving.Resolvable;
import com.gentics.api.portalnode.connector.PortalConnectorFactory;
import com.gentics.cr.CRConfig;
import com.gentics.cr.CRConfigFileLoader;
import com.gentics.cr.CRConfigUtil;
import com.gentics.cr.CRDatabaseFactory;
import com.gentics.cr.CRRequest;
import com.gentics.cr.CRResolvableBean;
import com.gentics.cr.RequestProcessor;
import com.gentics.cr.exceptions.CRException;
import com.gentics.cr.util.indexing.IndexController;

/**
* This class is used to resolve URLs to objects an vice versa.
*
* Sample Configuration:
*  main.properties
*  ================
*   before.transformer.2.ds-handle.type=jdbc
*  before.transformer.2.ds-handle.driverClass=com.mysql.jdbc.Driver
*  before.transformer.2.ds-handle.url=jdbc:mysql://localhost:3306/content
*  before.transformer.2.ds.cache=true
*  before.transformer.2.ds.cache.foreignlinkattributes=true
*  before.transformer.2.ds.cache.syncchecking=true
*  before.transformer.2.attribute=content
*  before.transformer.2.staticprefix=/Content.Node
*  before.transformer.2.hostprefix=http://www.mydomain.at
*  before.transformer.2.rule=object.obj_type==10007
*  before.transformer.2.searchconfig=searcher
*  before.transformer.2.indexconfig=indexer
*  before.transformer.2.transformerclass=\
*com.gentics.cr.lucene.indexer.transformer.LinkToPlinkTransformer
*  before.transformer.3.attribute=content
*  before.transformer.3.rule=object.obj_type==10007
*  before.transformer.3.transformerclass=\
*com.gentics.cr.lucene.indexer.transformer.LinkTargetTransformer
*  before.transformer.3.externaltarget=_blank
*  before.transformer.3.externalalt=Öffnet in einem neuen Fenster
*
*  indexer.properties
*  ==================
*  #file system location of index
*  index.1.indexLocations.1.path=${com.gentics.portalnode.confpath}/index/index
*  #index.1.indexLocations.1.path=RAM
*  #interval in seconds
*  index.1.interval=5
*  #job check interval
*  index.1.checkinterval=5
*  index.1.periodical=true
*  #job batch size
*  index.1.batchsize=10
*  #ContentRepository specific config
*  index.1.CR.1.rp.1.rpClass=com.gentics.cr.CRRequestProcessor
*  index.1.analyzerconfig\
*  =${com.gentics.portalnode.confpath}/rest/analyzer.properties
*  #Datasource
*  index.1.CR.1.rp.1.ds-handle.type=jdbc
*  index.1.CR.1.rp.1.ds-handle.driverClass=com.mysql.jdbc.Driver
*  index.1.CR.1.rp.1.ds-handle.url=jdbc:mysql://localhost:3306/content
*  #DO NOT USE CACHE FOR INDEXING
*  index.1.CR.1.rp.1.ds.cache=false
*  index.1.CR.1.rp.1.ds.cache.foreignlinkattributes=false
*  index.1.CR.1.rp.1.ds.cache.syncchecking=false
*  index.1.CR.1.rp.1.response-charset=UTF-8
*  index.1.CR.1.rp.1.binarytype=10008
*  index.1.CR.1.rp.1.foldertype=10002
*  index.1.CR.1.rp.1.pagetype=10007
*  #index.1.CR.2.ds-handle.portalnodedb=ccr
*  index.1.CR.1.rule=object.node_id==15 AND object.obj_type==10007
*  #index.1.CR.1.rule=10009==10008
*  index.1.CR.1.indexedAttributes=pub_dir,filename
*  index.1.CR.1.containedAttributes=pub_dir,filename
*  index.1.CR.1.idattribute=contentid
*  index.1.CR.1.batchsize=5
*  indexer.properties
*  ==================
*
* Last changed: $Date: 2010-01-18 15:57:21 +0100 (Mo, 18 Jän 2010) $
* @version $Revision: 401 $
* @author $Author: supnig@constantinopel.at $
*
*/
public class LucenePathResolver {

  /**
   * Configuration.
   */
  private CRConfig conf = null;
  /**
   * Logger.
   */
  private static Logger log = Logger.getLogger(LucenePathResolver.class);
  /**
   * IndexConfigKey.
   */
  private static final String INDEXER_CONFIG_FILE_KEY = "indexconfig";
  /**
   * SearchConfigKey.
   */
  private static final String SEARCH_CONFIG_FILE_KEY = "searchconfig";

  /**
   * IndexController.
   */
  private IndexController idx = null;
  /**
   * RequestProcessor.
   */
  private RequestProcessor rp = null;

  /**
   * Initialize the expression needed to resolve Objects from passed URLs. As
   * this uses a lot of time initalization in the constructor improves
   * performance. Initialize PathResolver once on Server startup.
   * @param config configuration
   *
   */
  public LucenePathResolver(final CRConfig config) {

    this.conf = config;
    String cxname = this.conf.getString(INDEXER_CONFIG_FILE_KEY);
    if (cxname == null) {
      cxname = "indexer";
    }
    CRConfigUtil idxConfig = new CRConfigFileLoader(cxname, null);

    String csname = this.conf.getString(SEARCH_CONFIG_FILE_KEY);
    if (csname == null) {
      csname = "searcher";
    }
    CRConfigUtil srcConfig = new CRConfigFileLoader(csname, null);

    idx = new IndexController(idxConfig);
    try {
      rp = srcConfig.getNewRequestProcessorInstance(1);
    } catch (CRException e) {
      log.error("Could not initialize searcher request processor." + "Check your searcher config.", e);
    }
  }

  /**
   * Destroys the PathResolver.
   */
  public final void destroy() {
    this.idx.stop();
  }

  /**
   * The Method looks in the repository with the expression initialized in the
   * constructor and tries to find a corrisponding object. This only works
   * correctly when only one node is in the repository, otherwise there may
   * bee more object with the same URL in the repository.
   * @param request
   * @return a Resolvable Object based on the passed URL.
   */
  public final CRResolvableBean getObject(final CRRequest request) {
    CRResolvableBean contentObject = null;
    String url = request.getUrl();
    if (url != null) {

      CRRequest r = new CRRequest();

      PathBean pb = new PathBean(request.getUrl());
      String path = pb.getPath();

      String filter = "";
      if (path == null || "".equals(path)) {
        filter = "(pub_dir:(/)) AND filename:(" + pb.getFilename() + ")";
      } else {
        filter = "(pub_dir:(" + pb.getPath() + ") OR pub_dir:(" + pb.getPath() + "/)) AND filename:("
            + pb.getFilename() + ")";
      }
      log.debug("Using filter: " + filter);
      r.setRequestFilter(filter);
      try {
        contentObject = rp.getFirstMatchingResolvable(r);
      } catch (CRException e) {
        log.error("Could not load object from path " + url, e);
      }

    }

    return contentObject;
  }

  /**
   * initializes a Resolvable Object and calls {@link com.gentics.cr.plink.LucenePathResolver#getPath(Resolvable)}.
   *
   * @param contentid contentid
   * @return string
   */
  public final String getPath(final String contentid) {

    Resolvable linkedObject = null;
    Datasource ds = null;
    try {
      ds = this.conf.getDatasource();
      // initialize linked Object
      linkedObject = PortalConnectorFactory.getContentObject(contentid, ds);
      return getPath(linkedObject);

    } catch (DatasourceNotAvailableException e) {
      log.error("Datasource error generating url for " + contentid);
    } finally {
      CRDatabaseFactory.releaseDatasource(ds);
    }

    // if the linked Object cannot be initialized return a dynamic URL
    //    this.log.info("Use dynamic url for " + contentid);
    //    return getDynamicUrl(contentid);
    return (null);
  }

  /**
   * @param linkedObject
   *            must be a Resolvable
   * @return a the URL from Gentics Content.Node. This expects the attributes
   *         filename and folder_id to be set for the passed object and the
   *         attribute pub_dir to be set for folders.
   */
  public final String getPath(final Resolvable linkedObject) {

    String filename = "";
    String pubdir = "";

    if (linkedObject != null) {

      // get filename from linkedObject
      filename = (String) linkedObject.get("filename");

      // Get folder Object from attribute folder_id and attribute pub_dir
      // from it
      Resolvable folder = (Resolvable) linkedObject.get("folder_id");
      if (folder != null) {
        pubdir = (String) folder.get("pub_dir");
      }
    }

    // If filename is empty or not set, no need to return an path
    if (filename != null && !"".equals(filename)) {

      return pubdir + filename;
    } else {

      // return a dynamic URL instead
      log.warn("Object " + linkedObject.get("contentid") + " has no filename.");
      //this.log.info("Use dynamic url for "
      //    + linkedObject.get("contentid"));

      //return getDynamicUrl((String) linkedObject.get("contentid"));
      return (null);
    }
  }

  /**
   * @param contentid contentid
   * @return a dynamic URL to suitable for CRServlet.
   */
  public final String getDynamicUrl(final String contentid) {

    return "?contentid=" + contentid;

  }

  /**
   * Get the alternate URL for the request.
   * This is used if the object cannot be resolved dynamically.
   * @param contentid String with the identifier of the object
   * @return String with the configured servlet / portal url.
   */
  public final String getAlternateUrl(final String contentid) {
    String url = null;
    String objtype = contentid.split("\\.")[0];
    if (objtype != null) {
      //try to get a specific URL for the objecttype
      url = conf.getString(CRConfig.ADVPLR_HOST + "." + objtype);
    }
    if (url == null) {
      //if we didn't get a specific URL take the generic one
      url = conf.getString(CRConfig.ADVPLR_HOST);
    }
    return url + contentid;
  }

  /**
   * @param contentid contentid
   * @param config config
   * @param request request
   * @return a dynamic URL to suitable for CRServlet.
   * Supports beautiful URLs,
   * therefore it needs to load DB Objects and Attributes
   */
  public final String getDynamicUrl(final String contentid, final CRConfig config, final CRRequest request) {
    String url = null;
    if (request != null) {
      url = (String) request.get("url");
      if (url == null) {
        return getDynamicUrl(contentid);
      } else {
        Datasource ds = null;
        String ret = null;
        try {
          //if there is an attribute URL the servlet was
          //called with a beautiful URL so give back a beautiful URL
          //check if valid local link
          String applicationrule = (String) config.get("applicationrule");
          ds = config.getDatasource();
          Expression expression = null;
          try {
            expression = PortalConnectorFactory.createExpression("object.contentid == '" + contentid
                + "' && " + applicationrule);
          } catch (ParserException exception) {
            log.error("Error while building expression object for " + contentid, exception);
            ret = getDynamicUrl(contentid);
          }

          DatasourceFilter filter = null;
          try {
            filter = ds.createDatasourceFilter(expression);
          } catch (ExpressionParserException e) {
            log.error("Error while building filter object for " + contentid, e);
            ret = getDynamicUrl(contentid);
          }
          int count = 0;
          try {
            count = ds.getCount(filter);
          } catch (DatasourceException e) {
            log.error("Error while querying for " + contentid, e);
            ret = getDynamicUrl(contentid);
          }

          if (count == 0 || "true".equals(config.getString(CRConfig.ADVPLR_HOST_FORCE))) {
            //not permitted or forced, build link
            ret = getAlternateUrl(contentid);
          } else {

            Resolvable plinkObject;
            try {
              plinkObject = PortalConnectorFactory.getContentObject(contentid, ds);
              //TODO: make this more beautiful and
              //compatible with portlets
              String filenameattribute = (String) config.get(CRConfig.ADVPLR_FN_KEY);
              String pubdirattribute = (String) config.get(CRConfig.ADVPLR_PB_KEY);
              String filename = (String) plinkObject.get(filenameattribute);
              String pubdir = (String) plinkObject.get(pubdirattribute);
              HttpServletRequest servletRequest = (HttpServletRequest) request.get("request");
              String contextPath = servletRequest.getContextPath();
              String servletPath = servletRequest.getServletPath();
              ret = contextPath + servletPath + pubdir + filename;
            } catch (DatasourceNotAvailableException e) {
              log.error("Error while getting object for " + contentid, e);
              ret = getDynamicUrl(contentid);
            }
          }
        } catch (Exception e) {
          log.error("Error while processing dynamic url", e);
        } finally {
          CRDatabaseFactory.releaseDatasource(ds);
        }
        return ret;
      }
    } else {
      return getAlternateUrl(contentid);
    }

  }

}
TOP

Related Classes of com.gentics.cr.plink.LucenePathResolver

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.