001/* 002 * Copyright 2011 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.glossary; 017 018import org.apache.commons.lang.StringUtils; 019 020import org.ametys.plugins.repository.AmetysRepositoryException; 021import org.ametys.plugins.repository.ModifiableTraversableAmetysObject; 022import org.ametys.plugins.repository.query.expression.Expression; 023import org.ametys.web.repository.site.Site; 024 025/** 026 * Glossary helper. 027 */ 028public final class GlossaryHelper 029{ 030 031 /** The glossary page tag. */ 032 public static final String GLOSSARY_PAGE_TAG = "GLOSSARY"; 033 034 private static final String __PLUGIN_NODE_NAME = "glossary"; 035 036 private static final String __DEFINITIONS_NODE_NAME = "ametys:wordDefinitions"; 037 038 private GlossaryHelper() 039 { 040 // Hides the default constructor. 041 } 042 043 /** 044 * Get the root plugin storage object. 045 * @param site the site. 046 * @return the root plugin storage object. 047 * @throws AmetysRepositoryException if a repository error occurs. 048 */ 049 public static ModifiableTraversableAmetysObject getPluginNode(Site site) throws AmetysRepositoryException 050 { 051 try 052 { 053 ModifiableTraversableAmetysObject pluginsNode = site.getRootPlugins(); 054 055 return getOrCreateNode(pluginsNode, __PLUGIN_NODE_NAME, "ametys:unstructured"); 056 } 057 catch (AmetysRepositoryException e) 058 { 059 throw new AmetysRepositoryException("Error getting the glossary plugin node for site " + site.getName(), e); 060 } 061 } 062 063 /** 064 * Get the word definitions storage node. 065 * @param site the site 066 * @param language the language. 067 * @return the word definitions storage node. 068 * @throws AmetysRepositoryException if a repository error occurs. 069 */ 070 public static ModifiableTraversableAmetysObject getDefinitionsNode(Site site, String language) throws AmetysRepositoryException 071 { 072 try 073 { 074 // Get the root plugin node. 075 ModifiableTraversableAmetysObject pluginNode = getPluginNode(site); 076 077 // Get or create the language node. 078 ModifiableTraversableAmetysObject langNode = getOrCreateNode(pluginNode, language, "ametys:unstructured"); 079 080 // Get or create the definitions container node in the language node and return it. 081 return getOrCreateNode(langNode, __DEFINITIONS_NODE_NAME, DefaultDefinitionFactory.DEFINITION_ROOT_NODE_TYPE); 082 } 083 catch (AmetysRepositoryException e) 084 { 085 throw new AmetysRepositoryException("Error getting the word definitions node for site " + site.getName() + " and language " + language, e); 086 } 087 } 088 089 /** 090 * Get the word definitions storage node. 091 * @param siteName the site name. 092 * @return the word definitions storage node. 093 */ 094 public static String getPluginNodePath(String siteName) 095 { 096 return String.format("//element(%s, ametys:site)/ametys-internal:plugins/%s", siteName, __PLUGIN_NODE_NAME); 097 } 098 099 /** 100 * Get the word definitions storage node. 101 * @param siteName the site name. 102 * @param language the language. 103 * @return the word definitions storage node. 104 */ 105 public static String getDefinitionsNodePath(String siteName, String language) 106 { 107 return getPluginNodePath(siteName) + "/" + language + "/" + __DEFINITIONS_NODE_NAME; 108 } 109 110 /** 111 * Get the word definitions storage node. 112 * @param siteName the site name. 113 * @param language the language. 114 * @param expression the expression of the repository querys 115 * @return the word definitions storage node. 116 */ 117 public static String getDefinitionQuery(String siteName, String language, Expression expression) 118 { 119 return getDefinitionsNodePath(siteName, language) + "/element(*, " + DefaultDefinitionFactory.DEFINITION_NODE_TYPE + ")[" + expression.build() + "] order by @ametys-internal:word"; 120 } 121 122 /** 123 * Get the word definitions storage node. 124 * @param siteName the site name. 125 * @param language the language. 126 * @param word the searched word 127 * @return the word definitions storage node. 128 */ 129 public static String getWordExistsQuery(String siteName, String language, String word) 130 { 131 String lowerWord = StringUtils.replace(word, "'", "''").toLowerCase(); 132 return getDefinitionsNodePath(siteName, language) + "/element(*, " + DefaultDefinitionFactory.DEFINITION_NODE_TYPE 133 + ")[fn:lower-case(@ametys-internal:word) = '" + lowerWord + "' or fn:lower-case(@ametys-internal:variants) = '" + lowerWord + "']"; 134 } 135 136 /** 137 * Get the word definitions storage node. 138 * @param siteName the site name. 139 * @param language the language. 140 * @param letter the first letter. 141 * @return the word definitions storage node. 142 */ 143 public static String getFirstLetterDefQuery(String siteName, String language, String letter) 144 { 145 String lowerLetter = letter.toLowerCase(); 146 return getDefinitionsNodePath(siteName, language) + "/element(*, " + DefaultDefinitionFactory.DEFINITION_NODE_TYPE 147 + ")[jcr:like(fn:lower-case(@ametys-internal:word), '" + lowerLetter + "%')] order by @ametys-internal:word"; 148 } 149 150 /** 151 * Get the word definitions storage node when first letter is not an alpha. 152 * @param siteName the site name. 153 * @param language the language. 154 * @return the word definitions storage node. 155 */ 156 public static String getNonAlphaFirstLetterDefQuery(String siteName, String language) 157 { 158 return getDefinitionsNodePath(siteName, language) + "/element(*, " + DefaultDefinitionFactory.DEFINITION_NODE_TYPE 159 + ")[not(jcr:like(fn:lower-case(@ametys-internal:word), 'a%')) " 160 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'b%'))" 161 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'c%'))" 162 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'd%'))" 163 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'e%'))" 164 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'f%'))" 165 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'g%'))" 166 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'h%'))" 167 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'u%'))" 168 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'j%'))" 169 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'k%'))" 170 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'l%'))" 171 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'm%'))" 172 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'n%'))" 173 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'o%'))" 174 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'p%'))" 175 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'q%'))" 176 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'r%'))" 177 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 's%'))" 178 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 't%'))" 179 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'u%'))" 180 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'v%'))" 181 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'w%'))" 182 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'x%'))" 183 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'y%'))" 184 + "and not(jcr:like(fn:lower-case(@ametys-internal:word), 'z%'))" 185 + "] order by @ametys-internal:word"; 186 } 187 188 private static ModifiableTraversableAmetysObject getOrCreateNode(ModifiableTraversableAmetysObject parentNode, String nodeName, String nodeType) throws AmetysRepositoryException 189 { 190 ModifiableTraversableAmetysObject definitionsNode; 191 if (parentNode.hasChild(nodeName)) 192 { 193 definitionsNode = parentNode.getChild(nodeName); 194 } 195 else 196 { 197 definitionsNode = parentNode.createChild(nodeName, nodeType); 198 parentNode.saveChanges(); 199 } 200 return definitionsNode; 201 } 202 203}