1 package fr.improve.struts.taglib.layout.skin; 2 3 import java.util.Enumeration ; 4 import java.util.HashMap ; 5 import java.util.Hashtable ; 6 import java.util.Locale ; 7 import java.util.Map ; 8 import java.util.MissingResourceException ; 9 import java.util.ResourceBundle ; 10 11 import javax.servlet.ServletRequest ; 12 import javax.servlet.http.HttpServletRequest ; 13 14 import fr.improve.struts.taglib.layout.formatter.AbstractFormatter; 15 import fr.improve.struts.taglib.layout.policy.AbstractPolicy; 16 import fr.improve.struts.taglib.layout.sort.SortRules; 17 import fr.improve.struts.taglib.layout.util.FieldInterface; 18 import fr.improve.struts.taglib.layout.util.FormUtilsInterface; 19 import fr.improve.struts.taglib.layout.util.IButtonImageRenderer; 20 import fr.improve.struts.taglib.layout.util.ICrumbRenderer; 21 import fr.improve.struts.taglib.layout.util.IPagerRenderer; 22 import fr.improve.struts.taglib.layout.util.LayoutUtils; 23 import fr.improve.struts.taglib.layout.util.TreeviewInterface; 24 25 40 public class Skin { 41 public static final String CSS_FILE = "skin"; 42 public static final String IMAGE_DIR = "directory.images"; 43 public static final String CONFIG_DIR = "directory.config"; 44 public static final String CSS_DIR = "directory.css"; 45 public static final String NULL_FIELDS = "display.null.fields"; 46 public static final String PANEL_CLASS = "panel.class"; 47 public static final String COLLECTION_CLASS = "collection.class"; 48 public static final String TABS_CLASS = "tabs.class"; 49 public static final String FIELD_CLASS = "field.class"; 50 public static final String FORMATTER_CLASS = "formatter.class"; 51 public static final String POLICY_CLASS = "policy.class"; 52 public static final String FOLLOW_LINKS_IF_CHANGED = "follow.change"; 53 public static final String DISPLAY_ERRORS_MESSAGE = "error.display"; 54 public static final String FOCUS_FIRST_ERROR_FIELD= "error.focus"; 55 public static final String SORT_KEEP_ERROR_MESSAGE = "sort.error.keep"; 56 public static final String SORT_TOKEN_REQUIRED = "sort.token.required"; 57 public static final String LINK_TOKEN_INCLUDE = "link.token.include"; 58 public static final String FORMUTIL_CLASSS = "formutils.class"; 59 public static final String TREEVIEW_CLASSS = "treeview.class"; 60 public static final String PAGER_CLASS = "pager.class"; 61 public static final String POPUP_CLASS = "popup.class"; 62 public static final String CRUMB_CLASS = "crumb.class"; 63 public static final String BUTTON_CLASS = "button.class"; 64 public static final String TREE_NUMBER_MENUS_LOADED = "tree.numberOfMenusLoaded"; 65 public static final String NESTED_COMPATILIBTY_PROPERTY = "nested.compatibility"; 66 public static final String TREEVIEW_ACTION = "treeview.action"; 67 public static final String EL_CHARACTER = "el.character"; 68 69 private static String resourcesName = "Struts-Layout"; 70 71 private static Map skins = new Hashtable (); 72 73 private ResourceBundle resources; 74 private ResourceBundle defaultResources; 75 private Locale locale; 76 private AbstractFormatter formatter; 77 private AbstractPolicy policy; 78 private FormUtilsInterface formutils; 79 private TreeviewInterface treeview; 80 private String configDir; 81 private String imageDir; 82 private String cssDir; 83 private boolean nestedCompatbility; 84 85 89 private boolean sortTokenRequired; 90 91 94 private boolean linkTokenRequired; 95 96 99 private int numberOfMenusLoaded; 100 101 private FieldInterface fieldInterface; 102 private IPagerRenderer pagerRenderer; 103 private ICrumbRenderer crumbRenderer; 104 private IButtonImageRenderer buttonRenderer; 105 106 109 private Map sortingRules = new HashMap (); 110 111 public static void setResourcesName(String in_name) { 112 resourcesName = in_name; 113 } 114 115 private Skin(String in_name, String in_locale) { 116 locale = new Locale (in_name, in_locale); 118 try { 119 resources = loadBundles(resourcesName, locale, this); 121 defaultResources = loadBundles("Struts-Layout", null, this); 122 123 String lc_formatterClass = getProperty(FORMATTER_CLASS); 125 if (lc_formatterClass!=null && lc_formatterClass.length()>0) { 126 formatter = (AbstractFormatter) loadClass(lc_formatterClass, this).newInstance(); 127 } 128 129 String lc_policyClass = getProperty(POLICY_CLASS); 131 if (lc_policyClass!=null && lc_policyClass.length()>0) { 132 policy = (AbstractPolicy) loadClass(lc_policyClass, this).newInstance(); 133 } 134 135 String lc_fieldInterfaceClass = getProperty(FIELD_CLASS); 137 fieldInterface = (FieldInterface) loadClass(lc_fieldInterfaceClass, this).newInstance(); 138 139 String lc_formUtilsClass = getProperty(FORMUTIL_CLASSS); 141 formutils = (FormUtilsInterface) loadClass(lc_formUtilsClass, this).newInstance(); 142 143 String lc_treeviewClass = getProperty(TREEVIEW_CLASSS); 145 treeview = (TreeviewInterface) loadClass(lc_treeviewClass, this).newInstance(); 146 147 String lc_pagerRendererClass = getProperty(PAGER_CLASS); 149 pagerRenderer = (IPagerRenderer) loadClass(lc_pagerRendererClass, this).newInstance(); 150 151 String lc_crumbRendererClass = getProperty(CRUMB_CLASS); 153 crumbRenderer = (ICrumbRenderer) loadClass(lc_crumbRendererClass, this).newInstance(); 154 155 String lc_buttonRendererClass = getProperty(BUTTON_CLASS); 157 buttonRenderer = (IButtonImageRenderer) loadClass(lc_buttonRendererClass, this).newInstance(); 158 159 configDir = getProperty(CONFIG_DIR); 161 imageDir = getProperty(IMAGE_DIR); 162 163 sortTokenRequired = Boolean.valueOf(getProperty(SORT_TOKEN_REQUIRED)).booleanValue(); 164 linkTokenRequired = Boolean.valueOf(getProperty(LINK_TOKEN_INCLUDE)).booleanValue(); 165 numberOfMenusLoaded = Integer.valueOf(getProperty(TREE_NUMBER_MENUS_LOADED)).intValue(); 166 nestedCompatbility = Boolean.valueOf(getProperty(NESTED_COMPATILIBTY_PROPERTY)).booleanValue(); 167 168 } catch (MissingResourceException e) { 169 throw new BadSkinConfigurationException(e); 170 } catch (ClassNotFoundException cnfe) { 171 throw new BadSkinConfigurationException(cnfe); 172 } catch (IllegalAccessException iae) { 173 throw new BadSkinConfigurationException(iae); 174 } catch (InstantiationException ie) { 175 throw new BadSkinConfigurationException(ie); 176 } catch (ClassCastException cce) { 177 throw new BadSkinConfigurationException(cce); 178 } 179 180 loadStringRules(); 181 182 try { 183 cssDir = getProperty(CSS_DIR); 184 } catch (MissingResourceException e) { 185 } 187 } 188 189 protected static ResourceBundle loadBundles(String in_name, Locale in_locale, Object in_object) { 190 ClassLoader lc_loader = Thread.currentThread().getContextClassLoader(); 191 if (lc_loader==null) { 192 lc_loader = in_object.getClass().getClassLoader(); 193 } 194 Locale lc_locale = in_locale; 195 if (lc_locale==null) { 196 lc_locale = Locale.getDefault(); 197 } 198 return ResourceBundle.getBundle(resourcesName, lc_locale, lc_loader); 199 } 200 201 protected static Class loadClass(String in_name, Object in_object) throws ClassNotFoundException { 202 ClassLoader lc_loader = Thread.currentThread().getContextClassLoader(); 203 if (lc_loader==null) { 204 lc_loader = in_object.getClass().getClassLoader(); 205 } 206 return lc_loader.loadClass(in_name); 207 } 208 209 212 protected void loadStringRules() { 213 Enumeration enumeration = resources.getKeys(); 214 while (enumeration.hasMoreElements()) { 215 String key = (String ) enumeration.nextElement(); 216 if (key.startsWith("sort.rules.") && key.endsWith(".class")) { 217 int start = 11; 219 int end = key.lastIndexOf('.'); 220 String locale = end>start ? key.substring(start,end) : ""; 221 String className = resources.getString(key).trim(); 222 try { 223 Class clazz = loadClass(className, this); 224 SortRules rules = (SortRules) clazz.newInstance(); 225 sortingRules.put(locale, rules); 226 } catch (ClassNotFoundException e) { 227 throw new BadSkinConfigurationException("String class rules " + className + " not found"); 228 } catch (InstantiationException e) { 229 throw new BadSkinConfigurationException("Could not instanciate class rules " + className + " : " + e.getMessage()); 230 } catch (IllegalAccessException e) { 231 throw new BadSkinConfigurationException("Could not instanciate class rules " + className + " : " + e.getMessage()); 232 } catch (ClassCastException e) { 233 throw new BadSkinConfigurationException("String class rules " + className + " is not an instance of SortRules"); 234 } 235 } 236 } 237 } 238 239 242 public SortRules getSortRules(Locale in_locale) { 243 if (in_locale==null) { 244 return (SortRules) sortingRules.get(""); 245 } else { 246 String key = in_locale.toString(); 247 SortRules rules = null; 248 while (rules==null && key!=null) { 249 rules = (SortRules) sortingRules.get(key); 250 if (rules==null) { 251 int position = key.indexOf('_'); 252 if (position!=-1) { 253 key = key.substring(0, position); 254 } else if (key!=null && key.length()>0){ 255 key = ""; 256 } else { 257 key = null; 258 } 259 } 260 } 261 return rules; 262 } 263 } 264 265 266 267 public static Skin getSkin(String in_name, String in_locale) { 268 if (LayoutUtils.getNoErrorMode()) { 269 return new Skin(in_name, in_locale); 272 } 273 Skin lc_skin = (Skin) skins.get(in_name + "_" + in_locale); 274 if (lc_skin==null) { 275 lc_skin = new Skin(in_name, in_locale); 276 skins.put(in_name + "_" + in_locale, lc_skin); 277 } 278 return lc_skin; 279 } 280 281 public String getImageDirectory(ServletRequest in_request) { 282 HttpServletRequest lc_request = (HttpServletRequest ) in_request; 283 if (imageDir.charAt(0)=='/') { 284 return imageDir; 285 } else { 286 return lc_request.getContextPath() + '/' + imageDir; 287 } 288 } 289 290 public void setImageDir(String in_imageDir) { 291 imageDir = in_imageDir; 292 } 293 294 public String getConfigDirectory(ServletRequest in_request) { 295 HttpServletRequest lc_request = (HttpServletRequest ) in_request; 296 if (configDir.charAt(0)=='/') { 297 return configDir; 298 } else { 299 return lc_request.getContextPath() + '/' + configDir; 300 } 301 } 302 303 public String getCssDirectory(ServletRequest in_request) { 304 if (cssDir==null || cssDir.length()==0) { 305 return getConfigDirectory(in_request); 306 } 307 HttpServletRequest lc_request = (HttpServletRequest ) in_request; 308 if (cssDir.charAt(0)=='/') { 309 return cssDir; 310 } else { 311 return lc_request.getContextPath() + '/' + cssDir; 312 } 313 } 314 315 public void setConfigDir(String in_configDir) { 316 configDir = in_configDir; 317 } 318 319 public boolean getDisplayNullFields() { 320 return "true".equalsIgnoreCase(getProperty(NULL_FIELDS)); 321 } 322 public boolean getFocusFirstErrorField() { 323 return "true".equalsIgnoreCase(getProperty(FOCUS_FIRST_ERROR_FIELD, "false")); 324 } 325 326 public boolean getSortKeepErrorMessage() { 327 return "true".equalsIgnoreCase(getProperty(SORT_KEEP_ERROR_MESSAGE, "true")); 328 } 329 330 public boolean getFollowLinkIfFormChanged() { 331 return "true".equalsIgnoreCase(getProperty(FOLLOW_LINKS_IF_CHANGED)); 332 } 333 334 public boolean getDisplayErrorMessage() { 335 return "true".equalsIgnoreCase(getProperty(DISPLAY_ERRORS_MESSAGE)); 336 } 337 338 public String getName() { 339 return locale.getLanguage(); 340 } 341 342 public String getLocale() { 343 return locale.getCountry(); 344 } 345 346 public String getCssFileName() { 347 String lc_fileName = getProperty(CSS_FILE); 348 if (lc_fileName==null || lc_fileName.length()==0) { 349 return getName() + ".css"; 350 } else { 351 return getProperty(CSS_FILE); 352 } 353 } 354 355 public Class getPanelClass(String in_model) { 356 Class lc_class = null; 357 try { 358 if (in_model==null) { 359 lc_class = loadClass(getProperty(PANEL_CLASS), this); 360 } else { 361 lc_class = loadClass(getProperty(PANEL_CLASS + "." + in_model), this); 362 } 363 } catch (ClassNotFoundException e) { 364 throw new BadSkinConfigurationException(e); 365 } 366 return lc_class; 367 } 368 369 public Class getPopupClass(String in_model) { 370 Class lc_class = null; 371 try { 372 if (in_model==null) { 373 lc_class = loadClass(getProperty(POPUP_CLASS), this); 374 } else { 375 lc_class = loadClass(getProperty(POPUP_CLASS + "." + in_model), this); 376 } 377 } catch (ClassNotFoundException e) { 378 throw new BadSkinConfigurationException(e); 379 } 380 return lc_class; 381 } 382 383 public Class getCollectionClass(String in_model) { 384 Class lc_class = null; 385 try { 386 if (in_model==null) { 387 lc_class = loadClass(getProperty(COLLECTION_CLASS), this); 388 } else { 389 lc_class = loadClass(getProperty(COLLECTION_CLASS + "." + in_model), this); 390 } 391 } catch (ClassNotFoundException e) { 392 throw new BadSkinConfigurationException(e); 393 } 394 return lc_class; 395 } 396 397 public Class getTabsClass() { 398 Class lc_class = null; 399 try { 400 lc_class = loadClass(getProperty(TABS_CLASS), this); 401 } catch (ClassNotFoundException e) { 402 throw new BadSkinConfigurationException(e); 403 } 404 return lc_class; 405 } 406 407 public FieldInterface getFieldInterface() { 408 return getFieldInterface(null); 409 } 410 411 public FieldInterface getFieldInterface(String in_model) { 412 if (in_model==null) { 413 return fieldInterface; 414 } else { 415 FieldInterface lc_interface = null; 416 try { 417 Class lc_class = loadClass(getProperty(FIELD_CLASS + "." + in_model), this); 418 lc_interface = (FieldInterface) lc_class.newInstance(); 419 } catch (ClassNotFoundException cnfe) { 420 throw new BadSkinConfigurationException(cnfe); 421 } catch (IllegalAccessException iae) { 422 throw new BadSkinConfigurationException(iae); 423 } catch (InstantiationException ie) { 424 throw new BadSkinConfigurationException(ie); 425 } 426 return lc_interface; 427 } 428 } 429 430 public IPagerRenderer getPagerRenderer() { 431 return pagerRenderer; 432 } 433 434 public ICrumbRenderer getCrumbRenderer(String in_model) { 435 if (in_model==null) { 436 return crumbRenderer; 437 } else { 438 ICrumbRenderer lc_interface = null; 439 try { 440 Class lc_class = loadClass(getProperty(CRUMB_CLASS + "." + in_model), this); 441 lc_interface = (ICrumbRenderer) lc_class.newInstance(); 442 } catch (Exception e) { 443 throw new BadSkinConfigurationException(e); 444 } 445 return lc_interface; 446 } 447 } 448 449 public IButtonImageRenderer getButtonRenderer(String in_model) { 450 if (in_model==null) { 451 return buttonRenderer; 452 } else { 453 throw new IllegalStateException ("Not implemented"); 454 } 455 } 456 457 public AbstractFormatter getFormatter() { 458 if (formatter==null) { 459 throw new BadSkinConfigurationException("Null formatter"); 460 } else { 461 return formatter; 462 } 463 } 464 465 public AbstractPolicy getPolicy() { 466 if (policy==null) { 467 throw new BadSkinConfigurationException("Null policy"); 468 } else { 469 return policy; 470 } 471 } 472 473 public FormUtilsInterface getFormUtils() { 474 return formutils; 475 } 476 477 public boolean isSortTokenRequired() { 478 return sortTokenRequired; 479 } 480 481 public boolean isLinkTokenRequired() { 482 return linkTokenRequired; 483 } 484 485 public String getProperty(String in_property) throws MissingResourceException { 486 String lc_value; 487 try { 488 lc_value = resources.getString(in_property); 489 } catch (MissingResourceException mre) { 490 lc_value = defaultResources.getString(in_property); 491 } 492 return lc_value; 493 } 494 495 public String getProperty(String in_property, String in_defaultValue) { 496 try { 497 String lc_value = getProperty(in_property); 498 return lc_value; 499 } catch (MissingResourceException e) { 500 return in_defaultValue; 501 } 502 503 } 504 505 public int getNumberOfMenusLoaded() 506 { 507 return numberOfMenusLoaded; 508 } 509 510 public boolean isNestedCompatible() { 511 return nestedCompatbility; 512 } 513 514 517 public TreeviewInterface getTreeviewInterface() { 518 return treeview; 519 } 520 521 524 public String getELCharacter() { 525 return getProperty(EL_CHARACTER, "$"); 526 } 527 } 528 | Popular Tags |