001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.tag; 020 021import lucee.commons.io.res.Resource; 022import lucee.commons.io.res.util.ResourceUtil; 023import lucee.commons.lang.StringUtil; 024import lucee.runtime.exp.ApplicationException; 025import lucee.runtime.exp.PageException; 026import lucee.runtime.ext.tag.TagImpl; 027import lucee.runtime.op.Caster; 028import lucee.runtime.search.SearchCollection; 029import lucee.runtime.search.SearchEngine; 030import lucee.runtime.search.SearchException; 031 032/** 033* Allows you to create and administer Collections. 034**/ 035public final class Collection extends TagImpl { 036 037 /** Specifies the action to perform. */ 038 private String action="list"; 039 040 /** */ 041 private Resource path; 042 043 /** Specifies a collection name or an alias if action = "map" */ 044 private String collection; 045 046 /** Name of the output variable (action=list) */ 047 private String name; 048 049 /** language of the collection (operators,stopwords) */ 050 private String language="english"; 051 052 //private boolean categories=false; 053 054 055 @Override 056 public void release() { 057 super.release(); 058 action="list"; 059 path=null; 060 collection=null; 061 name=null; 062 language="english"; 063 //categories=false; 064 } 065 066 067 /** 068 * @param categories the categories to set 069 * @throws ApplicationException 070 */ 071 public void setCategories(boolean categories) { 072 // Lucee always support categories 073 //this.categories = categories; 074 } 075 076 /** set the value action 077 * Specifies the action to perform. 078 * @param action value to set 079 **/ 080 public void setAction(String action) { 081 if(action==null) return; 082 this.action=action.toLowerCase().trim(); 083 } 084 085 086 public void setEngine(String engine) { 087 // This setter only exists for compatibility reasions to other CFML engines, the attribute is completely ignored by Lucee. 088 } 089 090 /** set the value path 091 * 092 * @param path value to set 093 * @throws PageException 094 **/ 095 public void setPath(String strPath) throws PageException { 096 if(strPath==null) return; 097 this.path=ResourceUtil.toResourceNotExisting(pageContext,strPath.trim() ); 098 //this.path=new File(path.toLowerCase().trim()); 099 100 pageContext.getConfig().getSecurityManager().checkFileLocation(this.path); 101 102 if(!this.path.exists()) { 103 Resource parent=this.path.getParentResource(); 104 if(parent!=null && parent.exists())this.path.mkdirs(); 105 else { 106 throw new ApplicationException("attribute path of the tag collection must be a existing directory"); 107 } 108 } 109 else if(!this.path.isDirectory()) 110 throw new ApplicationException("attribute path of the tag collection must be a existing directory"); 111 } 112 113 /** set the value collection 114 * Specifies a collection name or an alias if action = "map" 115 * @param collection value to set 116 **/ 117 public void setCollection(String collection) { 118 if(collection==null) return; 119 this.collection=collection.toLowerCase().trim(); 120 } 121 122 /** set the value name 123 * 124 * @param name value to set 125 **/ 126 public void setName(String name) { 127 if(name==null) return; 128 this.name=name.toLowerCase().trim(); 129 } 130 131 /** set the value language 132 * 133 * @param language value to set 134 **/ 135 public void setLanguage(String language) { 136 if(language==null) return; 137 this.language=validateLanguage(language); 138 } 139 140 public static String validateLanguage(String language) { 141 if(StringUtil.isEmpty(language,true)) 142 return "english"; 143 language=language.toLowerCase().trim(); 144 if("standard".equals(language)) 145 return "english"; 146 return language; 147 } 148 149 150 @Override 151 public int doStartTag() throws PageException { 152 //SerialNumber sn = pageContext.getConfig().getSerialNumber(); 153 //if(sn.getVersion()==SerialNumber.VERSION_COMMUNITY) 154 // throw new SecurityException("no access to this functionality with the "+sn.getStringVersion()+" version of lucee"); 155 156 try { 157 if(action.equals("create")) doCreate(); 158 else if(action.equals("repair")) doRepair(); 159 else if(action.equals("delete")) doDelete(); 160 else if(action.equals("optimize")) doOptimize(); 161 else if(action.equals("list")) doList(); 162 else if(action.equals("map")) doMap(); 163 else if(action.equals("categorylist"))doCategoryList(); 164 165 else throw new ApplicationException("Invalid value [" + action + "] for attribute action.", "allowed values are [create,repair,map,delete,optimize,list ]"); 166 } catch (SearchException e) { 167 throw Caster.toPageException(e); 168 } 169 return SKIP_BODY; 170 } 171 172 /** 173 * @throws SearchException 174 * @throws PageException 175 * 176 */ 177 private void doMap() throws SearchException, PageException { 178 required("collection",action,"collection",collection); 179 required("collection",action,"path",path); 180 getCollection().map(path); 181 } 182 183 /** 184 * Creates a query in the PageContext containing all available Collections of the current searchStorage 185 * @throws ApplicationException 186 * @throws PageException 187 * 188 */ 189 private void doList() throws ApplicationException, PageException { 190 required("collection",action,"name",name); 191 //if(StringUtil.isEmpty(name))throw new ApplicationException("for action list attribute name is required"); 192 pageContext.setVariable(name,getSearchEngine().getCollectionsAsQuery()); 193 } 194 195 196 private void doCategoryList() throws PageException, SearchException { 197 // check attributes 198 required("collection",action,"collection",collection); 199 required("collection",action,"name",name); 200 pageContext.setVariable(name,getCollection().getCategoryInfo()); 201 } 202 203 /** 204 * Optimizes the Collection 205 * @throws SearchException 206 * @throws PageException 207 * 208 */ 209 private void doOptimize() throws SearchException, PageException { 210 required("collection",action,"collection",collection); 211 getCollection().optimize(); 212 } 213 214 /** 215 * Deletes a Collection 216 * @throws SearchException 217 * @throws PageException 218 * 219 */ 220 private void doDelete() throws SearchException, PageException { 221 required("collection",action,"collection",collection); 222 getCollection().delete(); 223 } 224 225 /** 226 * 227 * @throws SearchException 228 * @throws PageException 229 * 230 */ 231 private void doRepair() throws SearchException, PageException { 232 required("collection",action,"collection",collection); 233 getCollection().repair(); 234 } 235 236 /** 237 * Creates a new collection 238 * @throws SearchException 239 * @throws PageException 240 * 241 */ 242 private void doCreate() throws SearchException, PageException { 243 required("collection",action,"collection",collection); 244 required("collection",action,"path",path); 245 getSearchEngine().createCollection(collection,path,language,SearchEngine.DENY_OVERWRITE); 246 } 247 248 /** 249 * Returns the Searchstorage defined in the Environment 250 * @return searchStorage 251 */ 252 private SearchEngine getSearchEngine() { 253 return pageContext.getConfig().getSearchEngine(); 254 } 255 256 /** 257 * the collection matching the collection name 258 * @return collection 259 * @throws SearchException 260 */ 261 private SearchCollection getCollection() throws SearchException { 262 return getSearchEngine().getCollectionByName(collection); 263 } 264 265 @Override 266 public int doEndTag() { 267 return EVAL_PAGE; 268 } 269}