blob: ffa0d287e43e9ea098af8ed9d0a7fbdd3d28ae54 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.ofbiz.webapp.region;
import java.net.URL;
import java.util.Map;
import javolution.util.FastMap;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.base.util.cache.UtilCache;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* A class to manage the region cache and read a region XML file
*/
public class RegionManager {
public static final String module = RegionManager.class.getName();
private static final UtilCache<URL, Map<String, Region>> regionCache = UtilCache.createUtilCache("webapp.Regions.Config", 0, 0);
protected URL regionFile = null;
public RegionManager(URL regionFile) {
this.regionFile = regionFile;
if (regionFile == null) throw new IllegalArgumentException("regionFile cannot be null");
//This may seem a bit funny, but we want to keep it in the cache so that it can be reloaded easily
// Also note that we do not check to see if it is already there, in all cases we want to re-load the definition
regionCache.put(regionFile, readRegionXml(regionFile));
}
public Map<String, Region> getRegions() {
Map<String, Region> regions = regionCache.get(regionFile);
if (regions == null) {
if (Debug.verboseOn()) Debug.logVerbose("Regions not loaded for " + regionFile + ", loading now", module);
regions = regionCache.putIfAbsentAndGet(regionFile, readRegionXml(regionFile));
}
return regions;
}
public Region getRegion(String regionName) {
if (regionFile == null) return null;
return getRegions().get(regionName);
}
public void putRegion(Region region) {
getRegions().put(region.getId(), region);
}
public Map<String, Region> readRegionXml(URL regionFile) {
Map<String, Region> regions = FastMap.newInstance();
Document document = null;
try {
document = UtilXml.readXmlDocument(regionFile, true);
} catch (java.io.IOException e) {
Debug.logError(e, module);
} catch (org.xml.sax.SAXException e) {
Debug.logError(e, module);
} catch (javax.xml.parsers.ParserConfigurationException e) {
Debug.logError(e, module);
}
if (document == null) return regions;
Element rootElement = document.getDocumentElement();
for (Element defineElement: UtilXml.childElementList(rootElement, "define")) {
addRegion(defineElement, regions);
}
return regions;
}
protected void addRegion(Element defineElement, Map<String, Region> regions) {
Region newRegion = null;
String idAttr = defineElement.getAttribute("id");
String templateAttr = defineElement.getAttribute("template");
String regionAttr = defineElement.getAttribute("region");
if (UtilValidate.isNotEmpty(templateAttr) && UtilValidate.isNotEmpty(regionAttr)) {
throw new IllegalArgumentException("Cannot use both template and region attributes");
}
if (UtilValidate.isNotEmpty(templateAttr)) {
newRegion = new Region(idAttr, templateAttr, null);
} else {
if (UtilValidate.isNotEmpty(regionAttr)) {
Region parentRegion = regions.get(regionAttr);
if (parentRegion == null) {
throw new IllegalArgumentException("can't find page definition attribute with this key: " + regionAttr);
}
newRegion = new Region(idAttr, parentRegion.getContent(), parentRegion.getSections());
} else {
throw new IllegalArgumentException("Must specify either the template or the region attribute");
}
}
regions.put(idAttr, newRegion);
for (Element putElement: UtilXml.childElementList(defineElement, "put")) {
newRegion.put(makeSection(putElement));
}
}
protected Section makeSection(Element putElement) {
String bodyContent = UtilXml.elementValue(putElement);
String section = putElement.getAttribute("section");
String info = putElement.getAttribute("info");
String content = putElement.getAttribute("content");
String type = putElement.getAttribute("type");
if (UtilValidate.isEmpty(type)) type = "default";
if (UtilValidate.isNotEmpty(bodyContent) && UtilValidate.isNotEmpty(content)) {
throw new IllegalArgumentException("Cannot use both content attribute and tag body text");
}
if (UtilValidate.isNotEmpty(bodyContent)) {
content = bodyContent;
type = "direct";
}
return new Section(section, info, content, type, this);
}
public static Region getRegion(URL regionFile, String regionName) {
if (regionFile == null) return null;
Map<String, Region> regions = regionCache.get(regionFile);
if (regions == null) return null;
return regions.get(regionName);
}
}