/** * Clones the specified object. Use clone() if Cloeable. Otherwise, try to serialize/deserialize * it by use of MarshalledObject. * * <p>If o is null, null is returned. * * @exception SystemException if failed to clone */ public static final Object clone(Object o) { if (o == null) return o; try { final Class<?> kls = o.getClass(); if (kls.isArray()) return ArraysX.clone(o); if (o instanceof Cloneable) { try { return kls.getMethod("clone").invoke(o); } catch (NoSuchMethodException ex) { if (log.debugable()) log.debug("No clone() for " + kls); } } // :TODO: MarshalledObject is said with very bad performance, change it // if exists other good deep clone method. return new MarshalledObject<Object>(o).get(); } catch (Exception ex) { throw SystemException.Aide.wrap(ex); } }
// -- private utilities --// private final Map loadLabels(Locale locale) { WaitLock lock = null; for (; ; ) { final Object o; synchronized (_syncLabels) { o = _syncLabels.get(locale); if (o == null) _syncLabels.put(locale, lock = new WaitLock()); // lock it } if (o instanceof Map) return (Map) o; if (o == null) break; // go to load the page // wait because some one is creating the servlet if (!((WaitLock) o).waitUntilUnlock(5 * 60 * 1000)) log.warning( "Take too long to wait loading labels: " + locale + "\nTry to load again automatically..."); } // for(;;) if (_jarcharset == null) _jarcharset = Library.getProperty("org.zkoss.util.label.classpath.charset", "UTF-8"); if (_warcharset == null) { _warcharset = Library.getProperty("org.zkoss.util.label.web.charset", null); if (_warcharset == null) _warcharset = Library.getProperty( "org.zkoss.util.label.WEB-INF.charset", "UTF-8"); // backward compatible } try { // get the class name if (locale != null) log.info("Loading labels for " + locale); Map labels = new HashMap(512); // 1. load from modules final ClassLocator locator = new ClassLocator(); for (Enumeration en = locator.getResources( locale == null ? "metainfo/i3-label.properties" : "metainfo/i3-label_" + locale + ".properties"); en.hasMoreElements(); ) { final URL url = (URL) en.nextElement(); load(labels, url, _jarcharset); } // 2. load from extra resource final List locators; synchronized (_locators) { locators = new LinkedList(_locators); } for (Iterator it = locators.iterator(); it.hasNext(); ) { Object o = it.next(); if (o instanceof LabelLocator) { final URL url = ((LabelLocator) o).locate(locale); if (url != null) load(labels, url, _warcharset); } else { final LabelLocator2 loc = (LabelLocator2) o; final InputStream is = loc.locate(locale); if (is != null) { final String cs = loc.getCharset(); load(labels, is, cs != null ? cs : _warcharset); } } } // Convert values to ExValue toExValue(labels); // merge with labels from 'super' locale if (locale != null) { final String lang = locale.getLanguage(); final String cnty = locale.getCountry(); final String var = locale.getVariant(); final Map superlabels = loadLabels( var != null && var.length() > 0 ? new Locale(lang, cnty) : cnty != null && cnty.length() > 0 ? new Locale(lang, "") : null); if (labels.isEmpty()) { labels = superlabels.isEmpty() ? Collections.EMPTY_MAP : superlabels; } else if (!superlabels.isEmpty()) { Map combined = new HashMap(superlabels); combined.putAll(labels); labels = combined; } } // add to map synchronized (_syncLabels) { _syncLabels.put(locale, labels); cloneLables(); } return labels; } catch (Throwable ex) { synchronized (_syncLabels) { _syncLabels.remove(locale); cloneLables(); } throw SystemException.Aide.wrap(ex); } finally { lock.unlock(); // unlock (always unlock to avoid deadlock) } }
/** * Loads, parses and returns the resource of the specified URI, or null if not found. The parser * is defined by the loader defined in {@link ResourceCache}. * * @param cache the resource cache. Note: its loader must extend from {@link ResourceLoader}. * @param path the URI path * @param extra the extra parameter that will be passed to {@link * ResourceLoader#parse(String,File,Object)} and {@link * ResourceLoader#parse(String,URL,Object)} */ public static final <V> V get( ResourceCache<V> cache, ServletContext ctx, String path, Object extra) { // 20050905: Tom Yeh // We don't need to handle the default name if user specifies only a dir // because it is handled by the container directly // And, web developer has to specify <welcome-file> in web.xml URL url = null; if (path == null || path.length() == 0) path = "/"; else if (path.charAt(0) != '/') { if (path.indexOf("://") > 0) { try { url = new URL(path); } catch (java.net.MalformedURLException ex) { throw new SystemException(ex); } } else path = '/' + path; } if (url == null) { if (path.startsWith("/~")) { final ServletContext ctx0 = ctx; final String path0 = path; final int j = path.indexOf('/', 2); final String ctxpath; if (j >= 0) { ctxpath = "/" + path.substring(2, j); path = path.substring(j); } else { ctxpath = "/" + path.substring(2); path = "/"; } final ExtendletContext extctx = Servlets.getExtendletContext(ctx, ctxpath.substring(1)); if (extctx != null) { url = extctx.getResource(path); // if (log.debugable()) log.debug("Resolving "+path0+" to "+url); if (url == null) return null; try { return cache.get(new ResourceInfo(path, url, extra)); } catch (Throwable ex) { final IOException ioex = getIOException(ex); if (ioex == null) throw SystemException.Aide.wrap(ex); log.warningBriefly("Unable to load " + url, ioex); } return null; } ctx = ctx.getContext(ctxpath); if (ctx == null) { // failed // if (log.debugable()) log.debug("Context not found: "+ctxpath); ctx = ctx0; path = path0; // restore } } final String flnm = ctx.getRealPath(path); if (flnm != null) { try { return cache.get(new ResourceInfo(path, new File(flnm), extra)); // it is loader's job to check the existence } catch (Throwable ex) { final IOException ioex = getIOException(ex); if (ioex == null) throw SystemException.Aide.wrap(ex); log.warningBriefly("Unable to load " + flnm, ioex); } return null; } } // try url because some server uses JAR format try { if (url == null) url = ctx.getResource(path); if (url != null) return cache.get(new ResourceInfo(path, url, extra)); } catch (Throwable ex) { final IOException ioex = getIOException(ex); if (ioex == null) throw SystemException.Aide.wrap(ex); log.warningBriefly("Unable to load " + path, ioex); } return null; }
/** * Setup parameter accordnig to ZkParameter annotation. * * @param <T> type of field. * @param annot the annotation with parameter definition * @param field the field to set * @param clazz class of the field and parameter */ protected static <T> void setupZkParameter( ZkParameter annot, String paramName, Class<T> clazz, Field field, Method method, Object instance) { T result = null; Map[] paramMaps = new Map[] { Executions.getCurrent().getArg(), Executions.getCurrent().getAttributes(), Executions.getCurrent().getParameterMap() }; Map paramMap = paramMaps[0]; for (Map map : paramMaps) { if (map.containsKey(paramName)) { paramMap = map; break; } } try { if (annot.required()) result = ZKHelper.getRequiredParameter(paramMap, paramName, clazz); else if (!paramMap.containsKey(paramName)) return; // optional parameter doesn't do anything else result = ZKHelper.getOptionalParameter(paramMap, paramName, clazz, null); } catch (IllegalArgumentException ex) { throw new IllegalArgumentException( "@ZkParameter(name='" + paramName + "', " + "required=" + (annot.required() ? "true" : "false") + ", " + "createIfNull=" + (annot.createIfNull() ? "true" : "false") + "): " + ex.getLocalizedMessage()); } if (result == null && annot.createIfNull()) try { result = (T) clazz.newInstance(); } catch (InstantiationException ex) { throw new InstantiationError( "@ZkParameter(name='" + paramName + "', " + "required=" + (annot.required() ? "true" : "false") + ", " + "createIfNull=" + (annot.createIfNull() ? "true" : "false") + ") - Parameter is null, unable to create new object with error: " + ex.getLocalizedMessage()); } catch (IllegalAccessException ex) { throw new InstantiationError( "@ZkParameter(name='" + paramName + "', " + "required=" + (annot.required() ? "true" : "false") + ", " + "createIfNull=" + (annot.createIfNull() ? "true" : "false") + ") - Parameter is null, unable to create new object, no public default constructor: " + ex.getLocalizedMessage()); } if (field != null) try { field.setAccessible(true); field.set(instance, result); field.setAccessible(false); } catch (IllegalArgumentException ex) { throw new IllegalArgumentException( "@ZkParameter(name='" + paramName + "', " + "required=" + (annot.required() ? "true" : "false") + ", " + "createIfNull=" + (annot.createIfNull() ? "true" : "false") + ") - Unable to set new value of field to '" + result + "': " + ex.getLocalizedMessage(), ex); } catch (IllegalAccessException ex) { throw SystemException.Aide.wrap(ex); } if (method != null) try { method.setAccessible(true); method.invoke(instance, new Object[] {result}); method.setAccessible(false); } catch (IllegalAccessException ex) { throw SystemException.Aide.wrap(ex); } catch (IllegalArgumentException ex) { throw new IllegalArgumentException( "@ZkParameter(name='" + paramName + "', " + "required=" + (annot.required() ? "true" : "false") + ", " + "createIfNull=" + (annot.createIfNull() ? "true" : "false") + ") - Unable to set new value of method to '" + result + "': " + ex.getClass() + " - " + ex.getLocalizedMessage(), ex); } catch (InvocationTargetException ex) { throw new IllegalArgumentException( "@ZkParameter(name='" + paramName + "', " + "required=" + (annot.required() ? "true" : "false") + ", " + "createIfNull=" + (annot.createIfNull() ? "true" : "false") + ") - Unable to set new value of method to '" + result + "', error in method invocation: " + ex.getClass() + " - " + (ex.getTargetException() == null ? ex.getLocalizedMessage() : ex.getTargetException().getLocalizedMessage()), ex); } }