1 16 package org.outerj.daisy.frontend; 17 18 import org.outerj.daisy.repository.*; 19 import org.outerj.daisy.repository.variant.*; 20 import org.outerj.daisy.emailnotifier.CollectionSubscriptionKey; 21 import org.apache.cocoon.forms.formmodel.Widget; 22 import org.apache.cocoon.forms.util.I18nMessage; 23 import org.apache.cocoon.forms.validation.ValidationErrorAware; 24 import org.apache.cocoon.forms.validation.ValidationError; 25 import org.apache.cocoon.forms.validation.WidgetValidator; 26 import org.apache.excalibur.xml.sax.XMLizable; 27 28 import java.util.HashSet ; 29 import java.util.Set ; 30 import java.util.regex.Matcher ; 31 import java.util.regex.Pattern ; 32 import java.io.LineNumberReader ; 33 import java.io.StringReader ; 34 import java.io.IOException ; 35 36 42 public class KeySetParser { 43 private static final Pattern LINE_PATTERN = Pattern.compile("([^,#]+)(\\s*,\\s*([a-zA-Z\\-_0-9*]+)(\\s*,\\s*([a-zA-Z\\-_0-9*]+)))\\s*(#.*)?"); 44 private static final Pattern LINE_PATTERN_VARIANT_OPTIONAL = Pattern.compile("([^,#]+)(\\s*,\\s*([a-zA-Z\\-_0-9*]+)(\\s*,\\s*([a-zA-Z\\-_0-9*]+))?)?\\s*(#.*)?"); 45 46 54 public static VariantKey[] parseVariantKeys(String input, VariantManager variantManager, boolean allowWildcards, boolean needAtLeastOne) throws Exception { 55 input = input == null ? "" : input; 56 Set keys = (Set )processInput(input, variantManager, false, new VariantsCustomiser(), "Unexpected error in variants list: ", allowWildcards, needAtLeastOne); 57 return (VariantKey[])keys.toArray(new VariantKey[keys.size()]); 58 } 59 60 public static CollectionSubscriptionKey[] parseCollectionKeys(String input, Repository repository) throws Exception { 61 input = input == null ? "" : input; 62 Set keys = (Set )processInput(input, repository.getVariantManager(), false, new CollectionsCustomiser(repository.getCollectionManager()), "Unexpected error in collection subscription list: ", true, false); 63 return (CollectionSubscriptionKey[])keys.toArray(new CollectionSubscriptionKey[keys.size()]); 64 } 65 66 public static WidgetValidator getVariantKeysWidgetValidator(VariantManager variantManager, boolean allowWildcards, boolean needAtLeastOne) { 67 return new KeyListValidator(variantManager, new VariantsCustomiser(), allowWildcards, needAtLeastOne); 68 } 69 70 public static WidgetValidator getCollectionSubscriptionKeysWidgetValidator(Repository repository, boolean allowWildcards, boolean needAtLeastOne) { 71 return new KeyListValidator(repository.getVariantManager(), 72 new CollectionsCustomiser(repository.getCollectionManager()), allowWildcards, needAtLeastOne); 73 } 74 75 79 private interface KeySetParserCustomiser { 80 long parseItem(String value) throws Exception ; 81 82 XMLizable validateItem(String value, long lineNumber) throws Exception ; 83 84 Object instantiateObject(long item, long branchId, long languageId); 85 } 86 87 private static class VariantsCustomiser implements KeySetParserCustomiser { 88 public long parseItem(String value) throws Exception { 89 try { 90 return Long.parseLong(value); 91 } catch (NumberFormatException e) { 92 throw new Exception ("invalid document ID."); 93 } 94 } 95 96 public XMLizable validateItem(String value, long lineNumber) { 97 try { 98 Long.parseLong(value); 99 return null; 100 } catch (NumberFormatException e) { 101 return new I18nMessage("keylist.invalid-docid", new String [] { String.valueOf(lineNumber)}); 102 } 103 } 104 105 public Object instantiateObject(long item, long branchId, long languageId) { 106 return new VariantKey(item, branchId, languageId); 107 } 108 } 109 110 private static class CollectionsCustomiser implements KeySetParserCustomiser { 111 private final CollectionManager collectionManager; 112 113 public CollectionsCustomiser(CollectionManager collectionManager) { 114 this.collectionManager = collectionManager; 115 } 116 117 public long parseItem(String value) throws Exception { 118 return collectionManager.getCollection(value, false).getId(); 119 } 120 121 public XMLizable validateItem(String value, long lineNumber) { 122 try { 123 collectionManager.getCollection(value, false).getId(); 124 return null; 125 } catch (CollectionNotFoundException e) { 126 return new I18nMessage("keylist.collection-does-not-exist", new String [] { String.valueOf(lineNumber)}); 127 } catch (RepositoryException e) { 128 return new I18nMessage("keylist.collection-retrieval-error", new String [] { String.valueOf(lineNumber), e.toString()}); 129 } 130 } 131 132 public Object instantiateObject(long item, long branchId, long languageId) { 133 return new CollectionSubscriptionKey(item, branchId, languageId); 134 } 135 } 136 137 143 private static Object processInput(String input, VariantManager variantManager, boolean validateMode, 144 KeySetParserCustomiser customiser, String exceptionPrefix, boolean allowWildcards, 145 boolean needsAtLeastOneEntry) throws Exception { 146 147 LineNumberReader reader = new LineNumberReader (new StringReader (input)); 148 149 XMLizable error = null; 151 boolean hasLines = false; 152 HashSet keys = validateMode ? null : new HashSet (); 154 155 String line; 156 try { 157 while ((line = reader.readLine()) != null) { 158 line = line.trim(); 159 if (line.length() > 0 && !(line.charAt(0) == '#')) { 160 Pattern pattern = allowWildcards ? LINE_PATTERN : LINE_PATTERN_VARIANT_OPTIONAL; 161 Matcher matcher = pattern.matcher(line); 162 if (!matcher.matches()) { 163 if (validateMode) { 164 error = new I18nMessage("keylist.entry-invalid", new String [] { String.valueOf(reader.getLineNumber())}); 165 break; 166 } else { 167 throw new Exception (exceptionPrefix + "entry on line " + reader.getLineNumber() + " is not in the correct format."); 168 } 169 } else { 170 long itemId = -1; 171 String itemString = matcher.group(1); 172 if (!(allowWildcards && itemString.equals("*"))) { 173 if (validateMode) { 174 error = customiser.validateItem(matcher.group(1), reader.getLineNumber()); 175 if (error != null) 176 break; 177 } else { 178 try { 179 itemId = customiser.parseItem(matcher.group(1)); 180 } catch (Exception e) { 181 throw new Exception (exceptionPrefix + "entry on line " + reader.getLineNumber() + " is not valid: " + e.toString()); 182 } 183 } 184 } 185 long branchId = allowWildcards ? -1 : Branch.MAIN_BRANCH_ID; 186 long languageId = allowWildcards ? -1 : Language.DEFAULT_LANGUAGE_ID; 187 String branch = matcher.group(3); 188 if (!(allowWildcards && branch.equals("*"))) { 189 if (branch != null) { 190 try { 191 branchId = variantManager.getBranch(branch, false).getId(); 192 } catch (BranchNotFoundException e) { 193 if (validateMode) { 194 error = new I18nMessage("keylist.branch-does-not-exist", new String [] { String.valueOf(reader.getLineNumber())}); 195 break; 196 } else { 197 throw new Exception (exceptionPrefix + "branch specified on line " + reader.getLineNumber() + " does not exist."); 198 } 199 } catch (RepositoryException e) { 200 if (validateMode) { 201 error = new I18nMessage("keylist.branch-retrieval-error", new String [] { String.valueOf(reader.getLineNumber()), e.getMessage()}); 202 break; 203 } else { 204 throw new Exception (exceptionPrefix + "problem getting branch specified on line " + reader.getLineNumber() + ": " + e.getMessage()); 205 } 206 } 207 } 208 } 209 String language = matcher.group(5); 210 if (!(allowWildcards && language.equals("*"))) { 211 if (language != null) { 212 try { 213 languageId = variantManager.getLanguage(language, false).getId(); 214 } catch (LanguageNotFoundException e) { 215 if (validateMode) { 216 error = new I18nMessage("keylist.lang-does-not-exist", new String [] { String.valueOf(reader.getLineNumber())}); 217 break; 218 } else { 219 throw new Exception (exceptionPrefix + "language specified on line " + reader.getLineNumber() + " does not exist."); 220 } 221 } catch (RepositoryException e) { 222 if (validateMode) { 223 error = new I18nMessage("keylist.lang-retrieval-error", new String [] { String.valueOf(reader.getLineNumber()), e.getMessage()}); 224 break; 225 } else { 226 throw new Exception (exceptionPrefix + "problem getting language specified on line " + reader.getLineNumber() + ": " + e.getMessage()); 227 } 228 } 229 } 230 } 231 if (validateMode) { 232 if (!hasLines) 233 hasLines = true; 234 } else { 235 keys.add(customiser.instantiateObject(itemId, branchId, languageId)); 236 } 237 } 238 } 239 } 240 } catch (IOException e) { 241 throw new Exception (exceptionPrefix + "highly unexpected IOException.", e); 242 } 243 244 if (validateMode) { 245 if (error == null && !hasLines && needsAtLeastOneEntry) 246 error = new I18nMessage("keylist.need-at-least-one-entry"); 247 248 return error; 249 } else { 250 return keys; 251 } 252 } 253 254 private static class KeyListValidator implements WidgetValidator { 255 private final VariantManager variantManager; 256 private final KeySetParserCustomiser customiser; 257 private final boolean allowWildcards; 258 private final boolean needAtLeastOne; 259 260 public KeyListValidator(VariantManager variantManager, KeySetParserCustomiser customiser, boolean allowWildcards, 261 boolean needAtLeastOne) { 262 this.variantManager = variantManager; 263 this.customiser = customiser; 264 this.allowWildcards = allowWildcards; 265 this.needAtLeastOne = needAtLeastOne; 266 } 267 268 public boolean validate(Widget widget) { 269 String input = (String )widget.getValue(); 270 if (input != null) { 271 XMLizable error = null; 272 try { 273 error = (XMLizable)processInput(input, variantManager, true, customiser, null, allowWildcards, needAtLeastOne); 274 } catch (Exception e) { 275 throw new RuntimeException ("Unexpected error during keylist validation: " + e.toString(), e); 276 } 277 if (error != null) { 278 ((ValidationErrorAware)widget).setValidationError(new ValidationError(error)); 279 return false; 280 } 281 } 282 return true; 283 } 284 } 285 } 286 | Popular Tags |