Issue #1870 add Python and XML Incremental Override, implemented for both Java
and Python Change-Id: I293b6abcdffbd2cef35e9b986362113186583c55 Former-commit-id: 27f86d4c39ce8b8e708408511c820a5dd765e4cb
This commit is contained in:
parent
da7a648a61
commit
288bd3b02c
6 changed files with 395 additions and 46 deletions
|
@ -1,4 +1,4 @@
|
||||||
##
|
# #
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
# This software was developed and / or modified by Raytheon Company,
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
#
|
#
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
#
|
#
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
# further licensing information.
|
# further licensing information.
|
||||||
##
|
# #
|
||||||
|
|
||||||
|
|
||||||
from java.lang import Integer, Float, Long, Boolean, String
|
from java.lang import Integer, Float, Long, Boolean, String
|
||||||
|
@ -86,6 +86,9 @@ def javaMapToPyDict(javaMap, customConverter=None):
|
||||||
return pyDict
|
return pyDict
|
||||||
|
|
||||||
def pyDictToJavaMap(pyDict):
|
def pyDictToJavaMap(pyDict):
|
||||||
|
if pyDict is None :
|
||||||
|
return None
|
||||||
|
|
||||||
if isinstance(pyDict, OrderedDict):
|
if isinstance(pyDict, OrderedDict):
|
||||||
jmap = LinkedHashMap()
|
jmap = LinkedHashMap()
|
||||||
else:
|
else:
|
||||||
|
@ -159,4 +162,3 @@ class JavaWrapperClass(object):
|
||||||
def toJavaObj(self):
|
def toJavaObj(self):
|
||||||
raise NotImplementedError, "Subclasses must override this method."
|
raise NotImplementedError, "Subclasses must override this method."
|
||||||
|
|
||||||
|
|
|
@ -77,11 +77,13 @@ class PathManager(IPathManager.IPathManager):
|
||||||
@summary: Returns the localization levels available for the file given
|
@summary: Returns the localization levels available for the file given
|
||||||
'''
|
'''
|
||||||
jtype = self._convertType(loctype)
|
jtype = self._convertType(loctype)
|
||||||
jMap = JUtil.javaMapToPyDict(self.jpathManager.getTieredLocalizationFile(jtype, name))
|
jMap = self.jpathManager.getTieredLocalizationFile(jtype, name)
|
||||||
|
iterator = jMap.entrySet().iterator()
|
||||||
vals = dict()
|
vals = dict()
|
||||||
for level in jMap:
|
while iterator.hasNext() :
|
||||||
jlevel = self._convertLevel(level)
|
nextValue = iterator.next()
|
||||||
vals[jlevel.name()] = LocalizationFile(jMap.get(level))
|
# the key of the entry set is a localization level, the value is a localization file
|
||||||
|
vals[nextValue.getKey().name()] = LocalizationFile(nextValue.getValue())
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
def listFiles(self, name, extensions, recursive, filesOnly, loctype=None, loclevel=None, locname=None):
|
def listFiles(self, name, extensions, recursive, filesOnly, loctype=None, loclevel=None, locname=None):
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
# #
|
||||||
|
# This software was developed and / or modified by Raytheon Company,
|
||||||
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
#
|
||||||
|
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
# This software product contains export-restricted data whose
|
||||||
|
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
# to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
# an export license or other authorization.
|
||||||
|
#
|
||||||
|
# Contractor Name: Raytheon Company
|
||||||
|
# Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
# Mail Stop B8
|
||||||
|
# Omaha, NE 68106
|
||||||
|
# 402.291.0100
|
||||||
|
#
|
||||||
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
# further licensing information.
|
||||||
|
# #
|
||||||
|
|
||||||
|
#
|
||||||
|
# Overrides python modules with each other and returns a new module
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# SOFTWARE HISTORY
|
||||||
|
#
|
||||||
|
# Date Ticket# Engineer Description
|
||||||
|
# ------------ ---------- ----------- --------------------------
|
||||||
|
# 03/12/13 mnash Initial Creation.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import imp
|
||||||
|
import inspect
|
||||||
|
from PathManager import PathManager
|
||||||
|
import LocalizationUtil
|
||||||
|
|
||||||
|
def override(name, loctype):
|
||||||
|
"""
|
||||||
|
Takes a name (filename and localization path) and the localization type and finds the
|
||||||
|
file and overrides it, and returns the module
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name : the name and path of the file in localization
|
||||||
|
loctype : a string representation of the localization type
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a module that has all the correct methods after being overridden
|
||||||
|
"""
|
||||||
|
pathManager = PathManager()
|
||||||
|
tieredFiles = pathManager.getTieredLocalizationFile(loctype, name)
|
||||||
|
levels = pathManager.getAvailableLevels()
|
||||||
|
lfiles = list()
|
||||||
|
for level in levels :
|
||||||
|
if tieredFiles.has_key(level) :
|
||||||
|
lfiles.append(tieredFiles[level].getPath())
|
||||||
|
themodule = _internalOverride(lfiles)
|
||||||
|
return themodule
|
||||||
|
|
||||||
|
def _internalOverride(files):
|
||||||
|
"""
|
||||||
|
Takes the files and overrides them
|
||||||
|
|
||||||
|
Args:
|
||||||
|
files : the files that are to be overridden
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a new module that contains all the necessary elements
|
||||||
|
"""
|
||||||
|
themodule = imp.new_module('tmpmodule')
|
||||||
|
# modules = list of all the modules
|
||||||
|
for module in files :
|
||||||
|
# load each module, temporarily
|
||||||
|
tmpmodule = LocalizationUtil.loadModule(module)
|
||||||
|
the_module = _combineMembers(tmpmodule, themodule)
|
||||||
|
return themodule
|
||||||
|
|
||||||
|
def _combineMembers(tocombine, finalmodule):
|
||||||
|
"""
|
||||||
|
Loops over the necessary parts of each module and decides how to combine them
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tocombine : the module to combine in
|
||||||
|
finalmodule : the module that is being combined into
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a new python module that was created above
|
||||||
|
"""
|
||||||
|
# get the functions
|
||||||
|
members = inspect.getmembers(tocombine, inspect.isfunction)
|
||||||
|
for member in members :
|
||||||
|
finalmodule.__setattr__(member[0], member[1])
|
||||||
|
|
||||||
|
# get the classes
|
||||||
|
classes = inspect.getmembers(tocombine, inspect.isclass)
|
||||||
|
for clazz in classes:
|
||||||
|
finalmodule.__setattr__(clazz[0], clazz[1])
|
||||||
|
|
||||||
|
for attr in dir(tocombine):
|
||||||
|
if attr.startswith('__') == False or attr.startswith('_') == False:
|
||||||
|
if hasattr(finalmodule, attr):
|
||||||
|
if isinstance(attr, dict):
|
||||||
|
# simply update dicts with the new keys
|
||||||
|
getattr(finalmodule, attr).update(getattr(tocombine, attr))
|
||||||
|
if isinstance(attr, list):
|
||||||
|
listattr = getattr(tocombine, attr)
|
||||||
|
for i in listattr:
|
||||||
|
# override each element in the list if it exists
|
||||||
|
getattr(finalmodule, attr)[i] = listattr[i]
|
||||||
|
else :
|
||||||
|
finalmodule.__setattr__(attr, getattr(tocombine, attr))
|
||||||
|
else :
|
||||||
|
if inspect.ismethod(attr) == False and inspect.isbuiltin(attr) == False and inspect.isclass(attr) == False:
|
||||||
|
finalmodule.__setattr__(attr, getattr(tocombine, attr))
|
||||||
|
return finalmodule
|
|
@ -0,0 +1,84 @@
|
||||||
|
# #
|
||||||
|
# This software was developed and / or modified by Raytheon Company,
|
||||||
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
#
|
||||||
|
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
# This software product contains export-restricted data whose
|
||||||
|
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
# to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
# an export license or other authorization.
|
||||||
|
#
|
||||||
|
# Contractor Name: Raytheon Company
|
||||||
|
# Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
# Mail Stop B8
|
||||||
|
# Omaha, NE 68106
|
||||||
|
# 402.291.0100
|
||||||
|
#
|
||||||
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
# further licensing information.
|
||||||
|
# #
|
||||||
|
|
||||||
|
#
|
||||||
|
# Overrides xml files with each other and returns a dict
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# SOFTWARE HISTORY
|
||||||
|
#
|
||||||
|
# Date Ticket# Engineer Description
|
||||||
|
# ------------ ---------- ----------- --------------------------
|
||||||
|
# 03/12/13 mnash Initial Creation.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from com.raytheon.uf.common.localization.overrides import XMLOverrider as JavaXMLOverrider
|
||||||
|
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationType as LocalizationType
|
||||||
|
|
||||||
|
def override(name, loctype):
|
||||||
|
"""
|
||||||
|
Takes a name (filename and localization path) and the localization type and finds the
|
||||||
|
file and overrides it using the Java overrider, and then takes that value and returns
|
||||||
|
a dictionary
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name : the name and path of the file in localization
|
||||||
|
loctype : a string representation of the localization type
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a dictionary representing the XML
|
||||||
|
"""
|
||||||
|
# call into the Java XMLOverrider class which will do the combining for us!
|
||||||
|
configurationNode = JavaXMLOverrider.override(LocalizationType.valueOf(loctype), name)
|
||||||
|
finalDict = _internalOverride(configurationNode)
|
||||||
|
return finalDict
|
||||||
|
|
||||||
|
def _internalOverride(configurationNode):
|
||||||
|
"""
|
||||||
|
Takes a configuration node from java and returns a dictionary of dictionaries corresponding to an XML file
|
||||||
|
|
||||||
|
Args:
|
||||||
|
configurationNode : the ConfigurationNode from Java
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a dictionary of dictionaries (key is the xml tag, value is its children or the value)
|
||||||
|
"""
|
||||||
|
theDict = dict()
|
||||||
|
for child in configurationNode.getChildren() :
|
||||||
|
# if there are children, then we can't just make this a value, so it needs to be a dict
|
||||||
|
if child.getChildrenCount() > 0 :
|
||||||
|
d = dict()
|
||||||
|
theDict[child.getName()] = _internalOverride(child, d)
|
||||||
|
else :
|
||||||
|
# if this key is already in the dictionary, add to the list if there is one, or make a new one
|
||||||
|
if theDict.has_key(child.getName()) :
|
||||||
|
if isinstance(theDict.__getitem__(child.getName()), list) :
|
||||||
|
theDict.__getitem__(child.getName()).append(child.getValue())
|
||||||
|
else :
|
||||||
|
l = list()
|
||||||
|
l.append(theDict.__getitem__(child.getName()))
|
||||||
|
l.append(str(child.getValue()))
|
||||||
|
theDict[child.getName()] = l
|
||||||
|
else :
|
||||||
|
theDict[child.getName()] = str(child.getValue())
|
||||||
|
return theDict
|
|
@ -8,11 +8,13 @@ Require-Bundle: org.apache.commons.lang,
|
||||||
com.raytheon.uf.common.serialization,
|
com.raytheon.uf.common.serialization,
|
||||||
com.raytheon.uf.common.serialization.comm;bundle-version="1.0.0",
|
com.raytheon.uf.common.serialization.comm;bundle-version="1.0.0",
|
||||||
com.raytheon.uf.common.auth,
|
com.raytheon.uf.common.auth,
|
||||||
com.raytheon.uf.common.status;bundle-version="1.12.1174"
|
com.raytheon.uf.common.status;bundle-version="1.12.1174",
|
||||||
|
org.apache.commons.configuration;bundle-version="1.6.0"
|
||||||
Eclipse-BuddyPolicy: registered, ext, global
|
Eclipse-BuddyPolicy: registered, ext, global
|
||||||
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
|
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
|
||||||
Export-Package: com.raytheon.uf.common.localization,
|
Export-Package: com.raytheon.uf.common.localization,
|
||||||
com.raytheon.uf.common.localization.exception,
|
com.raytheon.uf.common.localization.exception,
|
||||||
com.raytheon.uf.common.localization.msgs,
|
com.raytheon.uf.common.localization.msgs,
|
||||||
|
com.raytheon.uf.common.localization.overrides,
|
||||||
com.raytheon.uf.common.localization.stream
|
com.raytheon.uf.common.localization.stream
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.localization.overrides;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.configuration.CombinedConfiguration;
|
||||||
|
import org.apache.commons.configuration.ConfigurationException;
|
||||||
|
import org.apache.commons.configuration.XMLConfiguration;
|
||||||
|
import org.apache.commons.configuration.tree.NodeCombiner;
|
||||||
|
import org.apache.commons.configuration.tree.OverrideCombiner;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.localization.IPathManager;
|
||||||
|
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||||
|
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||||
|
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||||
|
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override a set of XML files incrementally.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Mar 14, 2013 mnash Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mnash
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class XMLOverrider {
|
||||||
|
private static final IUFStatusHandler handler = UFStatus
|
||||||
|
.getHandler(XMLOverrider.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes the information needed to get a file from localization using an
|
||||||
|
* {@link IPathManager}, and then combines them and returns.
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static CombinedConfiguration override(LocalizationType type,
|
||||||
|
String name) {
|
||||||
|
IPathManager manager = PathManagerFactory.getPathManager();
|
||||||
|
Map<LocalizationLevel, LocalizationFile> mapFiles = manager
|
||||||
|
.getTieredLocalizationFile(type, name);
|
||||||
|
|
||||||
|
List<File> files = new ArrayList<File>();
|
||||||
|
for (LocalizationLevel level : manager.getAvailableLevels()) {
|
||||||
|
files.add(mapFiles.get(level).getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
return override(files.toArray(new File[files.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes an array of {@link LocalizationFile} and returns a combined version
|
||||||
|
* of them.
|
||||||
|
*
|
||||||
|
* @param lFiles
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static CombinedConfiguration override(LocalizationFile... lFiles) {
|
||||||
|
File[] files = convertToFiles(lFiles);
|
||||||
|
return override(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide the override functionality for XML. This takes the XML files and
|
||||||
|
* integrates them together.
|
||||||
|
*/
|
||||||
|
public static CombinedConfiguration override(File... files) {
|
||||||
|
NodeCombiner combiner = new OverrideCombiner();
|
||||||
|
// lowest level first
|
||||||
|
XMLConfiguration[] configurations = new XMLConfiguration[files.length];
|
||||||
|
for (int i = 0; i < files.length; i++) {
|
||||||
|
try {
|
||||||
|
configurations[i] = new XMLConfiguration(files[i]);
|
||||||
|
} catch (ConfigurationException e) {
|
||||||
|
handler.handle(Priority.ERROR,
|
||||||
|
"Unable to make a new XML configuration", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CombinedConfiguration combinedConfiguration = new CombinedConfiguration(
|
||||||
|
combiner);
|
||||||
|
combinedConfiguration.setForceReloadCheck(true);
|
||||||
|
// loop through each xml configuration
|
||||||
|
for (XMLConfiguration config : configurations) {
|
||||||
|
combinedConfiguration.addConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
return combinedConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts localization files to files for use later
|
||||||
|
*
|
||||||
|
* @param lFiles
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static File[] convertToFiles(LocalizationFile[] lFiles) {
|
||||||
|
File[] files = new File[lFiles.length];
|
||||||
|
for (int i = 0; i < files.length; i++) {
|
||||||
|
File file = lFiles[i].getFile();
|
||||||
|
if (file != null && file.exists()) {
|
||||||
|
files[i] = file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue