package lt.insoft.commons.zk.util; import java.net.URL; import java.util.List; import java.util.Locale; import java.util.Set; import org.apache.commons.lang.reflect.FieldUtils; import org.zkoss.util.resource.LabelLocator; import org.zkoss.util.resource.Labels; import org.zkoss.util.resource.Locator; import org.zkoss.util.resource.Locators; import org.zkoss.util.resource.impl.LabelLoader; import org.zkoss.web.util.resource.ServletLabelLocator; import org.zkoss.zk.ui.WebApp; import org.zkoss.zk.ui.util.WebAppInit; import com.google.common.collect.Lists; import com.google.common.collect.Sets; public class FixLabelLoadersInit implements WebAppInit { private static final String ZK_CLASS_PATH_PREFIX = "~."; @Override public void init(WebApp wapp) throws Exception { LabelLoader loader = (LabelLoader) FieldUtils.readStaticField(Labels.class, "_loader", true); @SuppressWarnings("unchecked") Set locators = (Set) FieldUtils.readField(loader, "_locators", true); List list = Lists.newArrayList(locators); boolean modified = false; for (int i = 0; i < list.size(); i++) { Object element = list.get(i); if (element instanceof ServletLabelLocator) { String path = (String) FieldUtils.readField(element, "_path", true); if (path != null && path.startsWith(ZK_CLASS_PATH_PREFIX)) { list.set(i, new ExtraLabelLocator(path)); modified = true; } } } if (modified) { FieldUtils.writeField(loader, "_locators", Sets.newLinkedHashSet(list), true); } } private static class ExtraLabelLocator implements LabelLocator { private final String path; public ExtraLabelLocator(String path) { this.path = path; } @Override public URL locate(Locale locale) throws Exception { String propertiesPath = path; final int j = propertiesPath.lastIndexOf('.'); final String prefix = j >= 0 ? propertiesPath.substring(0, j) : propertiesPath; final String suffix = j >= 0 ? propertiesPath.substring(j) : ""; propertiesPath = locale == null ? prefix + suffix : prefix + '_' + locale + suffix; final Locator locator = Locators.getDefault(); return locator.getResource(propertiesPath.replace(ZK_CLASS_PATH_PREFIX, "")); } } }