Package com.dotmarketing.viewtools.content

Source Code of com.dotmarketing.viewtools.content.ContentMap

/**
*
*/
package com.dotmarketing.viewtools.content;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.dotcms.repackage.org.apache.commons.beanutils.BeanUtils;
import com.dotcms.repackage.org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;

import com.dotmarketing.beans.Host;
import com.dotmarketing.beans.Identifier;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.business.DotStateException;
import com.dotmarketing.business.PermissionAPI;
import com.dotmarketing.cache.FieldsCache;
import com.dotmarketing.cache.LiveCache;
import com.dotmarketing.cache.WorkingCache;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotSecurityException;
import com.dotmarketing.portlets.categories.model.Category;
import com.dotmarketing.portlets.contentlet.business.ContentletAPI;
import com.dotmarketing.portlets.contentlet.model.Contentlet;
import com.dotmarketing.portlets.fileassets.business.FileAsset;
import com.dotmarketing.portlets.fileassets.business.FileAssetAPI;
import com.dotmarketing.portlets.fileassets.business.IFileAsset;
import com.dotmarketing.portlets.files.business.FileAPI;
import com.dotmarketing.portlets.files.model.File;
import com.dotmarketing.portlets.folders.business.FolderAPI;
import com.dotmarketing.portlets.structure.model.Field;
import com.dotmarketing.portlets.structure.model.KeyValueFieldUtil;
import com.dotmarketing.portlets.structure.model.Structure;
import com.dotmarketing.util.Config;
import com.dotmarketing.util.InodeUtils;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.UtilMethods;
import com.dotmarketing.util.VelocityUtil;
import com.dotmarketing.velocity.VelocityServlet;
import com.dotmarketing.viewtools.ContentsWebAPI;
import com.liferay.portal.model.User;

/**
* The purpose of this object is to provide an easy way on the frontend of dotCMS
* to get at fields, categories, permissions and other related things surrounding content.
* From Velocity you should be able to do things like $content.myField where myfield is the
* velocity variable of a field on the content.
*
* On a technical note maintainers of this class need to ensure that Velocity's introspector's datacache
* doesn't grow out of control when pulling saying thousands of these objects. We have seen
* Velocity not do well when storing many categories in it's context.
* @author Jason Tesser
* @since 1.9.3
*/
public class ContentMap {

  private static final FileAPI fileAPI = APILocator.getFileAPI();
  private Contentlet content;
  private ContentletAPI conAPI;
  private PermissionAPI perAPI;
  private List<Field> fields;
  private Map<String,Field> fieldMap;
  private User user;
  private boolean EDIT_OR_PREVIEW_MODE;
  private Host host;
  private Structure structure;
  private String title;
  private Context context;

  public ContentMap(Contentlet content, User user, boolean EDIT_OR_PREVIEW_MODE, Host host, Context context) {
    this.content = content;
    this.conAPI = APILocator.getContentletAPI();
    this.perAPI = APILocator.getPermissionAPI();
    this.fields = FieldsCache.getFieldsByStructureInode(content.getStructureInode());
    this.user = user;
    this.EDIT_OR_PREVIEW_MODE = EDIT_OR_PREVIEW_MODE;
    this.host = host;
    this.context = context;
  }

  /**
   * Use to get a value of the field on a content returned from the ContentTool Viewtool
   * This method gets called automatically when you place a "." after the contentmap object in Velocity<br/>
   * EXAMPLE : $mycontent.headline will call this method and return the value for the headline field of a piece of content.<br/>
   * NOTE: This is the last thing that gets called meaning if you do $mycontent.urlMap it will call the actual getUrlMap because that
   * method exists. This is case sensitive and uses standard Java bean reflection. For those not familiar here take note that the way to
   * call the getUrlMap is $mycontent.urlMap the get is removed and the next letter us lowered.<br/>
   *
   * Notes and Examples on Field Types <br/>
   * CATEGORY FIELDS : The category field is a heavier pull.  It is retrieved lazily meaning not until you say $mycon.mycatfield will it get retrieved.
   * It is not a bad performance but certainly slower then not displaying the category fields. Searching for categories doesn't effect the speed at all
   * it is only displaying them that will. The value returned to Velocity are the actual Category Objects. You get an ArrayList of them<br/>
   * <br/>
   * FILE/IMAGE FIELDS: You can get File/Image fields as well. $con.myimage or $con.myfile. It will return a FileMap object which wraps the actual File object from dotCMS.It adds the uri as a variable.
   * All the objects have toString implemented on them which means you can spit it out in velocity and see what it available to you.<br/>
   * <br/>
   * BINARY FIELDS : You can also get at binary field types. $mycon.myBinaryField This return the BinaryMap object to you.<br/>
   * TAG FIELDS : You get a TagList which is an arrayList that lets you get at the raw tag value. Meaning a comma separated list of values. <br />
   * HOST FIELDS OR HOST : Will return a ContentMap of the host or for the Folder the actual Folder <br/>
   * MULTI SELECT FIELDS : Returns MultiSelectMap which provides you Lists for the Options Values and Labels as well as a List of the Selected Values for this Content<br/>
   * SELECT FIELDS : Returns SelectMap which provides you Lists for the Options Values and Labels as well as the Selected Value for this Content<br/>
   * RADIO FIELDS : Returns RadioMap which provides you Lists for the Options Values and Labels as well as the Selected Value for this Content<br/>
   * @param fieldVariableName The velocity Variable name from the structure.
   * @return
   */
  public Object get(String fieldVariableName) {
    try {
      Object ret = null;
      Field f = retriveField(fieldVariableName);
      if(f==null){
        if(fieldVariableName.equalsIgnoreCase("host")){
          try{
            return new ContentMap(conAPI.search("+type:content +live:true +deleted:false +identifier:" + content.getHost() , 1, -1, "modDate", user, true).get(0), user, EDIT_OR_PREVIEW_MODE, host,context);
          }catch (IndexOutOfBoundsException e) {
            Logger.debug(this, "Unable to get host on content");
            return null;
          }
        }else if(fieldVariableName.equalsIgnoreCase("title")){
          ret =  getContentletsTitle();
        }else if(fieldVariableName.equalsIgnoreCase("structure")){
          return getStructure();
        //http://jira.dotmarketing.net/browse/DOTCMS-6033
        }else if(fieldVariableName.contains("FileURI")){
          f = retriveField(fieldVariableName.replaceAll("FileURI", ""));
          if(f!=null && (f.getFieldType()!= null && f.getFieldType().equals(Field.FieldType.FILE.toString())
              || f.getFieldType().equals(Field.FieldType.IMAGE.toString()))){
            String fid = (String)conAPI.getFieldValue(content, f);
            if(!UtilMethods.isSet(fid)){
              return null;
            }
            Identifier i = APILocator.getIdentifierAPI().find(fid);
            IFileAsset file = null;
            String p = "";
            if (EDIT_OR_PREVIEW_MODE){
              p = WorkingCache.getPathFromCache(i.getURI(),InodeUtils.isSet(i.getHostId())?i.getHostId():host.getIdentifier());
            }else{
              p = LiveCache.getPathFromCache(i.getURI(),InodeUtils.isSet(i.getHostId())?i.getHostId():host.getIdentifier());
            }
            p = p.substring(5, p.lastIndexOf("."));
            if(i!=null && InodeUtils.isSet(i.getId()) && i.getAssetType().equals("contentlet")){
              return i.getPath();
            }
            file = fileAPI.find(p,user,false);
            if(file != null && UtilMethods.isSet(file.getInode())){
              return ((File)file).getURI();
            }else{
              return null;
            }
          }else{
            return null;
          }
        }else{
          return content.getMap().get(fieldVariableName);
        }
      }
      if(f != null && f.getFieldType().equals(Field.FieldType.CATEGORY.toString())){
        return perAPI.filterCollection(new ArrayList<Category>((Set<Category>)conAPI.getFieldValue(content, f)), PermissionAPI.PERMISSION_USE, true, user);
      }else if(f != null && (f.getFieldType().equals(Field.FieldType.FILE.toString()) || f.getFieldType().equals(Field.FieldType.IMAGE.toString()))){
        String fid = (String)conAPI.getFieldValue(content, f);
        if(!UtilMethods.isSet(fid)){
          return null;
        }
        Identifier i = APILocator.getIdentifierAPI().find(fid);
        FileMap fm = new FileMap();
        IFileAsset file = null;
        if (EDIT_OR_PREVIEW_MODE){
          String p = WorkingCache.getPathFromCache(i.getURI(), InodeUtils.isSet(i.getHostId())?i.getHostId():host.getIdentifier());
          p = p.substring(5, p.lastIndexOf("."));
          if(i!=null && InodeUtils.isSet(i.getId()) && i.getAssetType().equals("contentlet")){
            Contentlet fileAsset  = APILocator.getContentletAPI().find(p.substring(0, p.indexOf(java.io.File.separator)), user!=null?user:APILocator.getUserAPI().getAnonymousUser(), false);
            if(fileAsset != null && UtilMethods.isSet(fileAsset.getInode())){
                FileAssetMap fam=new FileAssetMap();
                            FileAsset fa=APILocator.getFileAssetAPI().fromContentlet(fileAsset);
                            fam.setBinary(FileAssetAPI.BINARY_FIELD, fa.getFileAsset());
                            BeanUtils.copyProperties(fam, fa);
                            return fam;
                //return new ContentMap(fileAsset, user, EDIT_OR_PREVIEW_MODE,host,context);
            }
          }else{
            file = fileAPI.find(p,user,true);
          }
//          file = (File)APILocator.getVersionableAPI().findWorkingVersion(i, File.class);
        }else{
          String p = LiveCache.getPathFromCache(i.getURI(),InodeUtils.isSet(i.getHostId())?i.getHostId():host.getIdentifier());
          p = p.substring(5, p.lastIndexOf("."));
          if(i!=null && InodeUtils.isSet(i.getId()) && i.getAssetType().equals("contentlet")){
            Contentlet fileAsset  = APILocator.getContentletAPI().find(p.substring(0, p.indexOf(java.io.File.separator)), user!=null?user:APILocator.getUserAPI().getAnonymousUser(), false);
            if(fileAsset != null && UtilMethods.isSet(fileAsset.getInode())){
              FileAssetMap fam=new FileAssetMap();
              FileAsset fa=APILocator.getFileAssetAPI().fromContentlet(fileAsset);
              fam.setBinary(FileAssetAPI.BINARY_FIELD, fa.getFileAsset());
              BeanUtils.copyProperties(fam, fa);
              return fam;
                //return new ContentMap(fileAsset, user, EDIT_OR_PREVIEW_MODE,host,context);
            }
          }else{
            file = fileAPI.find(p,user,true);
          }
//          file = (File) APILocator.getVersionableAPI().findLiveVersion(i, File.class);
        }
        if(file != null && UtilMethods.isSet(file.getInode())){
          BeanUtils.copyProperties(fm, file);
          return fm;
        }else{
          return null;
        }
      }else if(f != null && f.getFieldType().equals(Field.FieldType.BINARY.toString())){
          if(content.getStructure().getStructureType()==Structure.STRUCTURE_TYPE_FILEASSET && f.getVelocityVarName().equalsIgnoreCase("fileasset")) {
              // http://jira.dotmarketing.net/browse/DOTCMS-7406
              FileAssetMap fam=new FileAssetMap();
              FileAsset fa=APILocator.getFileAssetAPI().fromContentlet(content);
              fam.setBinary(FileAssetAPI.BINARY_FIELD, fa.getFileAsset());
                    BeanUtils.copyProperties(fam, fa);
                    return fam;
          }
          else {
            BinaryMap bm = new BinaryMap(content,f);
            return bm;
          }
      }else if(f != null && f.getFieldType().equals(Field.FieldType.TAG.toString())){
        return new TagList((String)conAPI.getFieldValue(content, f));
      }else if(f != null && f.getFieldType().equals(Field.FieldType.HOST_OR_FOLDER.toString())){
        if(FolderAPI.SYSTEM_FOLDER.equals(content.getFolder())){
          try{
            return new ContentMap(conAPI.search("+type:content +live:true +deleted:false +identifier:" + content.getHost(),1,-1,"modDate",user,true).get(0),user, EDIT_OR_PREVIEW_MODE, host, context);
          }catch (IndexOutOfBoundsException e) {
            Logger.debug(this, "Unable to get host on content");
            return null;
          }
        }else{
          return APILocator.getFolderAPI().find(content.getFolder(), user, true);
        }
      }else if(f != null && f.getFieldType().equals(Field.FieldType.SELECT.toString())){
        return new SelectMap(f, content);
      }else if(f != null && f.getFieldType().equals(Field.FieldType.RADIO.toString())){
        return new RadioMap(f, content);
      }else if(f != null && f.getFieldType().equals(Field.FieldType.MULTI_SELECT.toString())){
        return new MultiSelectMap(f, content);
      }else if(f != null && f.getFieldType().equals(Field.FieldType.CHECKBOX.toString())){
        return new CheckboxMap(f, content);
      }else if(f != null && f.getFieldType().equals(Field.FieldType.KEY_VALUE.toString())){
          final String jsonData=(String)conAPI.getFieldValue(content, f);
        Map<String,Object> keyValueMap = KeyValueFieldUtil.JSONValueToHashMap(jsonData);
        //needs to be ordered
        Map<String,Object> retMap = new java.util.LinkedHashMap<String,Object>() {
            @Override
            public String toString() {
                return jsonData;
            }
        };
        for(String key :keyValueMap.keySet()){
          retMap.put(key.replaceAll("\\W",""), keyValueMap.get(key));
        }
        retMap.put("keys", retMap.keySet());
        retMap.put("map", keyValueMap);
        return retMap;
      }

      //ret could have been set by title
      if(ret == null){
        ret = conAPI.getFieldValue(content, f);
      }

      //handle Velicty Code
      if(ret != null && (f == null || f.getFieldType().equals(Field.FieldType.TEXT.toString()) || f.getFieldType().equals(Field.FieldType.TEXT_AREA.toString()) || f.getFieldType().equals(Field.FieldType.CUSTOM_FIELD.toString()) || f.getFieldType().equals(Field.FieldType.WYSIWYG.toString())) && (ret.toString().contains("#") || ret.toString().contains("$"))){
        VelocityEngine ve = VelocityUtil.getEngine();
        Template template = null;
        StringWriter sw = new StringWriter();
        VelocityServlet.velocityCtx.set(context);
        template = ve.getTemplate((EDIT_OR_PREVIEW_MODE ? "working/":"live/") + content.getInode() + "_" + f.getInode() + "." + Config.getStringProperty("VELOCITY_FIELD_EXTENSION"));
        template.merge(context, sw);
        ret = sw.toString();
      }
      return ret;
    } catch (Exception e) {
      Logger.error(ContentMap.class,"Unable to retrive Field or Content: " + e.getMessage());
      Logger.debug(ContentMap.class,"Unable to retrive Field or Content: " + e.getMessage(),e);
      return null;
    }
  }

  /**
   * Returns the URLMap if it exists for a piece of content. <br/>
   * EXAMPLE : $mycontent.urlMap OR $mycontent.getUrlMap() both of these work the same.
   * @return
   */
  public String getUrlMap(){
    String result = null;
    try {
      result = conAPI.getUrlMapForContentlet(content, user, true);
    } catch (Exception e) {
      Logger.warn(ContentsWebAPI.class, e.toString());
    }
    return result;
  }

  private Field retriveField(String fieldVariableName) throws Exception{
    if(fieldMap == null){
      fieldMap = UtilMethods.convertListToHashMap(fields, "getVelocityVarName", String.class);
    }
    return fieldMap.get(fieldVariableName);
  }

  public Structure getStructure() {
    structure = content.getStructure();
    return structure;
  }

  public String getContentletsTitle() {
    title = content.getTitle();
    return title;
  }
 
  public boolean isLive() throws Exception {
      return content.isLive();
  }
  public boolean isWorking() throws Exception {
      return content.isWorking();
  }

  public String toString() {
    getContentletsTitle();
    getStructure();
    return ToStringBuilder.reflectionToString(this);
  }

}
TOP

Related Classes of com.dotmarketing.viewtools.content.ContentMap

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.