Merge branch 'development' into development_on_RHEL6
Former-commit-id:8fb79e7b73
[formerly8fb79e7b73
[formerly 13d284277bed2f0f731547ec443a262556df997c]] Former-commit-id:c42f931118
Former-commit-id:2b95bcfb31
This commit is contained in:
commit
e7d8e5e560
8 changed files with 480 additions and 204 deletions
|
@ -45,6 +45,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Mar 16, 2012 mpduff Initial creation.
|
* Mar 16, 2012 mpduff Initial creation.
|
||||||
* Dec 17, 2012 1434 mpduff Don't allow underscores in name.
|
* Dec 17, 2012 1434 mpduff Don't allow underscores in name.
|
||||||
|
* Nov 14, 2013 2538 mpduff Check for same name entered.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -159,23 +160,25 @@ public class FileNameDlg extends CaveSWTDialog {
|
||||||
* OK Button action handler.
|
* OK Button action handler.
|
||||||
*/
|
*/
|
||||||
private boolean handleOk() {
|
private boolean handleOk() {
|
||||||
if ((nameTxt.getText() != null) && (!nameTxt.getText().isEmpty())
|
String name = nameTxt.getText().trim();
|
||||||
&& (!nameTxt.getText().contains("_"))) {
|
|
||||||
setReturnValue(nameTxt.getText());
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
String title;
|
String title;
|
||||||
String message;
|
String message;
|
||||||
if (nameTxt.getText() == null || nameTxt.getText().isEmpty()) {
|
if (name == null || name.isEmpty()) {
|
||||||
title = "Name Required";
|
title = "Name Required";
|
||||||
message = "Name required. A Subscription Name must be entered.";
|
message = "Name required. A Subscription Name must be entered.";
|
||||||
} else {
|
} else if (name.equals(origName)) {
|
||||||
|
title = "Different Name Required";
|
||||||
|
message = "A different name must be used.";
|
||||||
|
} else if (name.contains("_") || name.contains(" ")) {
|
||||||
title = "Name Invalid";
|
title = "Name Invalid";
|
||||||
message = "Underscore is not a valid character for a subscription name.";
|
message = "Underscore/space is not a valid character for a subscription name.";
|
||||||
|
} else {
|
||||||
|
setReturnValue(name);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataDeliveryUtils.showMessage(getShell(), SWT.OK, title, message);
|
DataDeliveryUtils.showMessage(getShell(), SWT.OK, title, message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -54,10 +54,12 @@ import com.raytheon.uf.common.datadelivery.registry.PointDataSet;
|
||||||
import com.raytheon.uf.common.datadelivery.registry.SiteSubscription;
|
import com.raytheon.uf.common.datadelivery.registry.SiteSubscription;
|
||||||
import com.raytheon.uf.common.datadelivery.registry.Subscription;
|
import com.raytheon.uf.common.datadelivery.registry.Subscription;
|
||||||
import com.raytheon.uf.common.datadelivery.registry.Time;
|
import com.raytheon.uf.common.datadelivery.registry.Time;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler;
|
||||||
import com.raytheon.uf.common.datadelivery.request.DataDeliveryPermission;
|
import com.raytheon.uf.common.datadelivery.request.DataDeliveryPermission;
|
||||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||||
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
import com.raytheon.uf.common.registry.ebxml.RegistryUtil;
|
||||||
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
|
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
|
||||||
|
import com.raytheon.uf.common.registry.handler.RegistryObjectHandlers;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
@ -133,6 +135,7 @@ import com.raytheon.viz.ui.presenter.IDisplay;
|
||||||
* Oct 15, 2013 2477 mpduff Remove debug code.
|
* Oct 15, 2013 2477 mpduff Remove debug code.
|
||||||
* Oct 23, 2013 2484 dhladky Unique ID for subscriptions updated.
|
* Oct 23, 2013 2484 dhladky Unique ID for subscriptions updated.
|
||||||
* Oct 25, 2013 2292 mpduff Move overlap processing to edex.
|
* Oct 25, 2013 2292 mpduff Move overlap processing to edex.
|
||||||
|
* Nov 14, 2013 2538 mpduff Added check for duplicate subscription.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author mpduff
|
* @author mpduff
|
||||||
|
@ -498,6 +501,22 @@ public abstract class SubsetManagerDlg extends CaveSWTDialog implements
|
||||||
boolean valid = this.validated(false);
|
boolean valid = this.validated(false);
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
// Check for existing subscription
|
||||||
|
ISubscriptionHandler handler = RegistryObjectHandlers
|
||||||
|
.get(ISubscriptionHandler.class);
|
||||||
|
try {
|
||||||
|
if (handler.getByName(nameText.getText()) != null) {
|
||||||
|
String message = "A query with this name already exists.\n\nPlease enter a different query name.";
|
||||||
|
DataDeliveryUtils.showMessage(getShell(), SWT.ERROR,
|
||||||
|
"Duplicate Query Name", message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (RegistryHandlerException e) {
|
||||||
|
statusHandler
|
||||||
|
.handle(Priority.PROBLEM,
|
||||||
|
"Unable to check for an existing subscription by name.",
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
|
||||||
AdhocSubscription as = createSubscription(new AdhocSubscription(),
|
AdhocSubscription as = createSubscription(new AdhocSubscription(),
|
||||||
Network.OPSNET);
|
Network.OPSNET);
|
||||||
|
|
11
deltaScripts/14.2.1/dropRecco.sh
Normal file
11
deltaScripts/14.2.1/dropRecco.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# DR #2505 Disable deployment of recco plugin
|
||||||
|
|
||||||
|
PSQL="/awips2/psql/bin/psql"
|
||||||
|
|
||||||
|
SQL_COMMAND="
|
||||||
|
delete from plugin_info where name = 'recco';
|
||||||
|
drop table if exists recco;
|
||||||
|
drop sequence if exists reccoseq;
|
||||||
|
"
|
||||||
|
${PSQL} -U awips -d metadata -c "${SQL_COMMAND}"
|
|
@ -19,9 +19,8 @@
|
||||||
# #
|
# #
|
||||||
|
|
||||||
#
|
#
|
||||||
# Methods to aid in using the path manager from Python as well as other features.
|
# Provides a method to dynamically load a python module into memory. The method
|
||||||
# Contains internal classes to help with the transition from strings in Python
|
# was relocated to this module from LocalizationUtil.
|
||||||
# to Java Localizationlevel and LocalizationType
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -29,53 +28,9 @@
|
||||||
#
|
#
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 03/12/13 mnash Initial Creation.
|
# 11/11/13 bkowal Initial Creation.
|
||||||
# 11/06/13 2086 bkowal Add the containing directory to the
|
|
||||||
# PYTHONPATH long enough to import
|
|
||||||
# the module.
|
|
||||||
#
|
#
|
||||||
#
|
import os, sys, imp
|
||||||
#
|
|
||||||
|
|
||||||
import os
|
|
||||||
import imp
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationType as JavaLocalizationType, LocalizationContext_LocalizationLevel as JavaLocalizationLevel
|
|
||||||
|
|
||||||
class LocalizationLevel(object):
|
|
||||||
'''
|
|
||||||
@summary: Can use cmp() to compare the levels, and can use values() to get all possible levels
|
|
||||||
'''
|
|
||||||
@staticmethod
|
|
||||||
def cmp(level1, level2):
|
|
||||||
return JavaLocalizationLevel.compare(level1,level2)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def values():
|
|
||||||
jvals = JavaLocalizationLevel.values()
|
|
||||||
vals = list()
|
|
||||||
for val in jvals :
|
|
||||||
vals.append(val.name())
|
|
||||||
return vals
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def valueOf(value):
|
|
||||||
return JavaLocalizationLevel.valueOf(value)
|
|
||||||
|
|
||||||
class LocalizationType(object):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def values():
|
|
||||||
jvals = JavaLocalizationType.values()
|
|
||||||
vals = list()
|
|
||||||
for val in jvals :
|
|
||||||
vals.append(val.name())
|
|
||||||
return vals
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def valueOf(value):
|
|
||||||
return JavaLocalizationType.valueOf(value)
|
|
||||||
|
|
||||||
def loadModule(filename):
|
def loadModule(filename):
|
||||||
'''
|
'''
|
|
@ -30,15 +30,13 @@
|
||||||
# 03/12/13 mnash Initial Creation.
|
# 03/12/13 mnash Initial Creation.
|
||||||
# 11/04/13 2086 bkowal Updated to merge classes - both legacy and non-legacy.
|
# 11/04/13 2086 bkowal Updated to merge classes - both legacy and non-legacy.
|
||||||
# Minimum to Maximum level of retrieval can now be specified.
|
# Minimum to Maximum level of retrieval can now be specified.
|
||||||
|
# 11/12/13 2540 bkowal Relocated common methods to PythonOverriderCore.py.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
import os
|
import PythonOverriderCore
|
||||||
import imp
|
|
||||||
import types
|
|
||||||
from PathManager import PathManager
|
from PathManager import PathManager
|
||||||
import LocalizationUtil
|
|
||||||
|
|
||||||
def importModule(name, loctype='COMMON_STATIC', level=None):
|
def importModule(name, loctype='COMMON_STATIC', level=None):
|
||||||
"""
|
"""
|
||||||
|
@ -56,134 +54,11 @@ def importModule(name, loctype='COMMON_STATIC', level=None):
|
||||||
pathManager = PathManager()
|
pathManager = PathManager()
|
||||||
tieredFiles = pathManager.getTieredLocalizationFile(loctype, name)
|
tieredFiles = pathManager.getTieredLocalizationFile(loctype, name)
|
||||||
availableLevels = pathManager.getAvailableLevels()
|
availableLevels = pathManager.getAvailableLevels()
|
||||||
if level == None:
|
levels = PythonOverriderCore._buildLocalizationLevelsList(availableLevels, level)
|
||||||
levels = availableLevels
|
|
||||||
else:
|
|
||||||
# ensure that the specified level is actually a legitimate level
|
|
||||||
if level not in availableLevels:
|
|
||||||
raise LookupError('An invalid level has been specified!')
|
|
||||||
|
|
||||||
levels = []
|
|
||||||
try:
|
|
||||||
levelIdx = availableLevels.index(level)
|
|
||||||
levels = availableLevels[:levelIdx + 1]
|
|
||||||
except ValueError:
|
|
||||||
# ignore; the exception should never be thrown, we verify that the specified level
|
|
||||||
# is valid in the previous if statement
|
|
||||||
pass
|
|
||||||
|
|
||||||
lfiles = []
|
lfiles = []
|
||||||
for _level in levels :
|
for _level in levels :
|
||||||
if _level in tieredFiles:
|
if _level in tieredFiles:
|
||||||
lfiles.append(tieredFiles[_level].getPath())
|
lfiles.append(tieredFiles[_level].getPath())
|
||||||
themodule = _internalOverride(lfiles)
|
themodule = PythonOverriderCore._internalOverride(lfiles)
|
||||||
return themodule
|
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)
|
|
||||||
themodule = _combineMembers(tmpmodule, themodule)
|
|
||||||
return themodule
|
|
||||||
|
|
||||||
def _combineMembers(tocombine, combinationresult):
|
|
||||||
for attr in dir(tocombine):
|
|
||||||
if attr.startswith('__') or attr.startswith('_') or isType(attr, types.BuiltinFunctionType):
|
|
||||||
# skip
|
|
||||||
continue
|
|
||||||
|
|
||||||
# is the element a class?
|
|
||||||
if isType(getattr(tocombine, attr), types.ClassType):
|
|
||||||
combinationresult = _mergeClasses(tocombine, combinationresult, attr)
|
|
||||||
else:
|
|
||||||
# absolute override
|
|
||||||
combinationresult = _mergeAttributes(tocombine, combinationresult, attr)
|
|
||||||
|
|
||||||
return combinationresult
|
|
||||||
|
|
||||||
def _mergeClasses(source, target, className):
|
|
||||||
sourceClass = getattr(source, className)
|
|
||||||
targetClass = getattr(target, className, None)
|
|
||||||
|
|
||||||
if (targetClass == None):
|
|
||||||
return _mergeAttributes(source, target, className)
|
|
||||||
|
|
||||||
legacyMode = (hasattr(sourceClass, '__class__') == False)
|
|
||||||
|
|
||||||
# verify that both classes are either legacy for current style.
|
|
||||||
if ((hasattr(targetClass, '__class__') == False) != legacyMode):
|
|
||||||
raise Exception("A legacy python class cannot be merged with a non-legacy python class!")
|
|
||||||
|
|
||||||
# ensure that the classes are not exactly the same (breaks the legacy merge).
|
|
||||||
if compareClasses(sourceClass, targetClass):
|
|
||||||
# nothing to merge
|
|
||||||
return target
|
|
||||||
|
|
||||||
for attr in dir(sourceClass):
|
|
||||||
# include private attributes because this is a class?
|
|
||||||
# methods cannot just be merged into a class, so skip them.
|
|
||||||
if isType(attr, types.BuiltinFunctionType) or isType(attr, types.MethodType) or \
|
|
||||||
attr.startswith('__') or attr.startswith('_'):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# do we need to worry about nested classes?
|
|
||||||
if isType(getattr(sourceClass, attr), types.ClassType):
|
|
||||||
target = _mergeClasses(source, target, attr)
|
|
||||||
|
|
||||||
attributeName = className + '.' + attr
|
|
||||||
target = _mergeAttributes(source, target, attributeName)
|
|
||||||
|
|
||||||
# complete the merge / override of methods.
|
|
||||||
exec(_buildMergeDirective(className, legacyMode))
|
|
||||||
return _mergeAttributes(source, target, className)
|
|
||||||
|
|
||||||
def _buildMergeDirective(className, legacyMode):
|
|
||||||
if (legacyMode):
|
|
||||||
return 'source.' + className + '.__bases__ = (target.' + className + ',)'
|
|
||||||
else:
|
|
||||||
return 'source.' + className + ' = type("' + className + \
|
|
||||||
'", (target.' + className + ',), dict(source.' + className + '.__dict__))'
|
|
||||||
|
|
||||||
def isType(object, type):
|
|
||||||
return type(object) == type
|
|
||||||
|
|
||||||
def compareClasses(clazz1, clazz2):
|
|
||||||
clazz1Attr = dir(clazz1)
|
|
||||||
clazz2Attr = dir(clazz2)
|
|
||||||
|
|
||||||
if (len(clazz1Attr) != len(clazz2Attr)):
|
|
||||||
return False
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
while i < len(clazz1Attr):
|
|
||||||
# compare the names
|
|
||||||
if (clazz1Attr[i] != clazz2Attr[i]):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# compare the attributes directly
|
|
||||||
attr1 = getattr(clazz1, clazz1Attr[i])
|
|
||||||
attr2 = getattr(clazz2, clazz2Attr[i])
|
|
||||||
if (attr1 != attr2):
|
|
||||||
return False
|
|
||||||
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _mergeAttributes(source, target, attributeName):
|
|
||||||
|
|
||||||
mergeDirective = 'target.' + attributeName + ' = source.' + attributeName
|
|
||||||
exec(mergeDirective)
|
|
||||||
|
|
||||||
return target
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
# #
|
||||||
|
# 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.
|
||||||
|
# #
|
||||||
|
|
||||||
|
#
|
||||||
|
# Used to merge two ore more python modules and returns a new module. This set of methods
|
||||||
|
# are compatible with and used by both the Jep Python Overrider solution and the Pure
|
||||||
|
# (outside of Jep, no Java dependencies) Python Overrider solution.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# SOFTWARE HISTORY
|
||||||
|
#
|
||||||
|
# Date Ticket# Engineer Description
|
||||||
|
# ------------ ---------- ----------- --------------------------
|
||||||
|
# 11/12/13 bkowal Initial Creation.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
import os, imp, types
|
||||||
|
import ModuleUtil
|
||||||
|
|
||||||
|
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 = ModuleUtil.loadModule(module)
|
||||||
|
themodule = _combineMembers(tmpmodule, themodule)
|
||||||
|
return themodule
|
||||||
|
|
||||||
|
def _buildLocalizationLevelsList(availableLevels, desiredLevel):
|
||||||
|
if desiredLevel == None:
|
||||||
|
return availableLevels
|
||||||
|
else:
|
||||||
|
# ensure that the specified level is actually a legitimate level
|
||||||
|
if desiredLevel not in availableLevels:
|
||||||
|
raise LookupError('An invalid level has been specified!')
|
||||||
|
|
||||||
|
levels = []
|
||||||
|
try:
|
||||||
|
levelIdx = availableLevels.index(desiredLevel)
|
||||||
|
levels = availableLevels[:levelIdx + 1]
|
||||||
|
except ValueError:
|
||||||
|
# ignore; the exception should never be thrown, we verify that the specified level
|
||||||
|
# is valid in the previous if statement
|
||||||
|
pass
|
||||||
|
|
||||||
|
return levels
|
||||||
|
|
||||||
|
def _combineMembers(tocombine, combinationresult):
|
||||||
|
for attr in dir(tocombine):
|
||||||
|
if attr.startswith('__') or attr.startswith('_') or isinstance(attr, types.BuiltinFunctionType):
|
||||||
|
# skip
|
||||||
|
continue
|
||||||
|
|
||||||
|
# is the element a class?
|
||||||
|
if isinstance(getattr(tocombine, attr), types.ClassType) \
|
||||||
|
or isinstance(getattr(tocombine, attr), types.TypeType):
|
||||||
|
combinationresult = _mergeClasses(tocombine, combinationresult, attr)
|
||||||
|
else:
|
||||||
|
# absolute override
|
||||||
|
combinationresult = _mergeAttributes(tocombine, combinationresult, attr)
|
||||||
|
|
||||||
|
return combinationresult
|
||||||
|
|
||||||
|
def _mergeClasses(source, target, className):
|
||||||
|
sourceClass = getattr(source, className)
|
||||||
|
targetClass = getattr(target, className, None)
|
||||||
|
|
||||||
|
if (targetClass == None):
|
||||||
|
return _mergeAttributes(source, target, className)
|
||||||
|
|
||||||
|
legacyMode = (hasattr(sourceClass, '__class__') == False)
|
||||||
|
|
||||||
|
# verify that both classes are either legacy for current style.
|
||||||
|
if ((hasattr(targetClass, '__class__') == False) != legacyMode):
|
||||||
|
raise Exception("A legacy python class cannot be merged with a non-legacy python class!")
|
||||||
|
|
||||||
|
# ensure that the classes are not exactly the same (breaks the legacy merge).
|
||||||
|
if _compareClasses(sourceClass, targetClass):
|
||||||
|
# nothing to merge
|
||||||
|
return target
|
||||||
|
|
||||||
|
for attr in dir(sourceClass):
|
||||||
|
# include private attributes because this is a class?
|
||||||
|
# methods cannot just be merged into a class, so skip them.
|
||||||
|
if isinstance(attr, types.BuiltinFunctionType) \
|
||||||
|
or isinstance(attr, types.MethodType) \
|
||||||
|
or attr.startswith('__') or attr.startswith('_'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# do we need to worry about nested classes?
|
||||||
|
if isinstance(getattr(sourceClass, attr), types.ClassType) \
|
||||||
|
or isinstance(getattr(sourceClass, attr), types.TypeType):
|
||||||
|
target = _mergeClasses(source, target, attr)
|
||||||
|
|
||||||
|
attributeName = className + '.' + attr
|
||||||
|
target = _mergeAttributes(source, target, attributeName)
|
||||||
|
|
||||||
|
# complete the merge / override of methods.
|
||||||
|
exec(_buildMergeDirective(className, legacyMode))
|
||||||
|
return _mergeAttributes(source, target, className)
|
||||||
|
|
||||||
|
def _buildMergeDirective(className, legacyMode):
|
||||||
|
if (legacyMode):
|
||||||
|
return 'source.' + className + '.__bases__ = (target.' + className + ',)'
|
||||||
|
else:
|
||||||
|
return 'source.' + className + ' = type("' + className + \
|
||||||
|
'", (target.' + className + ',), dict(source.' + className + '.__dict__))'
|
||||||
|
|
||||||
|
def _compareClasses(clazz1, clazz2):
|
||||||
|
clazz1Attr = dir(clazz1)
|
||||||
|
clazz2Attr = dir(clazz2)
|
||||||
|
|
||||||
|
if (len(clazz1Attr) != len(clazz2Attr)):
|
||||||
|
return False
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < len(clazz1Attr):
|
||||||
|
# compare the names
|
||||||
|
if (clazz1Attr[i] != clazz2Attr[i]):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# compare the attributes directly
|
||||||
|
attr1 = getattr(clazz1, clazz1Attr[i])
|
||||||
|
attr2 = getattr(clazz2, clazz2Attr[i])
|
||||||
|
if (attr1 != attr2):
|
||||||
|
return False
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _mergeAttributes(source, target, attributeName):
|
||||||
|
|
||||||
|
mergeDirective = 'target.' + attributeName + ' = source.' + attributeName
|
||||||
|
exec(mergeDirective)
|
||||||
|
|
||||||
|
return target
|
|
@ -0,0 +1,254 @@
|
||||||
|
# #
|
||||||
|
# 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.
|
||||||
|
# #
|
||||||
|
|
||||||
|
#
|
||||||
|
# The pure python module override solution. Merges multiple python modules retrieved
|
||||||
|
# from localization.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# SOFTWARE HISTORY
|
||||||
|
#
|
||||||
|
# Date Ticket# Engineer Description
|
||||||
|
# ------------ ---------- ----------- --------------------------
|
||||||
|
# 03/12/13 bkowal Initial Creation.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
import os, tempfile, shutil
|
||||||
|
import numpy
|
||||||
|
import PythonOverriderCore
|
||||||
|
from ufpy import ThriftClient
|
||||||
|
from dynamicserialize.dstypes.com.raytheon.uf.common.auth.resp import SuccessfulExecution
|
||||||
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization import LocalizationContext
|
||||||
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization.msgs import ListUtilityCommand
|
||||||
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization.msgs import UtilityRequestMessage
|
||||||
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization import LocalizationLevel
|
||||||
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization import LocalizationType
|
||||||
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization.stream import LocalizationStreamGetRequest
|
||||||
|
|
||||||
|
BUFFER_SIZE = 512 * 1024
|
||||||
|
availableLevels = ['BASE', 'CONFIGURED', 'SITE', 'USER']
|
||||||
|
|
||||||
|
def importModule(name, localizationHost, localizationPort, localizedSite, localizationUser=None,
|
||||||
|
loctype='COMMON_STATIC', level=None):
|
||||||
|
'''
|
||||||
|
@param name: the name of the localization file
|
||||||
|
@param localizationHost: the EDEX server that the localization should be
|
||||||
|
retrieved from
|
||||||
|
@param localizationPort: the port that will be used to connect to the
|
||||||
|
EDEX server
|
||||||
|
@param localizedSite: the site that localization information should be
|
||||||
|
retrieved for (if applicable)
|
||||||
|
@param localizationUser: the user that localization information should
|
||||||
|
be retrieved for (if applicable)
|
||||||
|
@param loctype: the type of localization files to retrieve
|
||||||
|
@param level: the minimum level that localization files should be retrieved
|
||||||
|
for
|
||||||
|
@return: the merged module
|
||||||
|
@summary: this is the pure python (no jep dependencies) version of the python overrider
|
||||||
|
'''
|
||||||
|
|
||||||
|
# determine which localization levels files need to be retrieved for
|
||||||
|
levels = PythonOverriderCore._buildLocalizationLevelsList(availableLevels, level)
|
||||||
|
|
||||||
|
# create a thrift instance
|
||||||
|
thrift = ThriftClient.ThriftClient(localizationHost, localizationPort, '/services')
|
||||||
|
|
||||||
|
# retrieve a list of the localization files that will need to be merged
|
||||||
|
serverResponse = \
|
||||||
|
_executeLocalizationFileListRetrieval(name, levels, localizedSite,
|
||||||
|
localizationUser, loctype, thrift)
|
||||||
|
# download the localization files
|
||||||
|
lfiles = _downloadLocalizationFiles(serverResponse, thrift, name)
|
||||||
|
# complete the module merge
|
||||||
|
return _executeModuleMerge(lfiles)
|
||||||
|
|
||||||
|
def _executeLocalizationFileListRetrieval(filename, localizationLevels, localizedSite,
|
||||||
|
localizationUser, loctype, thrift):
|
||||||
|
'''
|
||||||
|
@param filename: the name of the localization file
|
||||||
|
@param localizationLevels: a list of localization levels that should be checked
|
||||||
|
for the specified localization file
|
||||||
|
@param localizedSite: the site that localization information should be
|
||||||
|
retrieved for (if applicable)
|
||||||
|
@param localizationUser: the user that localization information should
|
||||||
|
be retrieved for (if applicable)
|
||||||
|
@param loctype: the type of localization files to retrieve
|
||||||
|
@param thrift: an instance of the thrift client used to communicate
|
||||||
|
with EDEX
|
||||||
|
@return: a list of the localization files associated with the specified
|
||||||
|
file name wrapped in a server response
|
||||||
|
@summary: this function will execute a list utility command via thrift to
|
||||||
|
retrieve a list of localization files that match the specified file name,
|
||||||
|
that match the specified localization type, and that can be found within the
|
||||||
|
specified localization levels.
|
||||||
|
'''
|
||||||
|
|
||||||
|
directory = os.path.dirname(filename)
|
||||||
|
|
||||||
|
cmds = []
|
||||||
|
|
||||||
|
# prepare the localization type
|
||||||
|
localizationType = LocalizationType(loctype)
|
||||||
|
|
||||||
|
# build the request message
|
||||||
|
req = UtilityRequestMessage()
|
||||||
|
for level in localizationLevels:
|
||||||
|
cmd = ListUtilityCommand()
|
||||||
|
cmd.setSubDirectory(directory)
|
||||||
|
cmd.setRecursive(False)
|
||||||
|
cmd.setFilesOnly(True)
|
||||||
|
cmd.setLocalizedSite(localizedSite)
|
||||||
|
|
||||||
|
# prepare the localization level
|
||||||
|
localizationLevel = LocalizationLevel(level)
|
||||||
|
|
||||||
|
# create a localization context
|
||||||
|
localizationContext = LocalizationContext()
|
||||||
|
localizationContext.setLocalizationType(localizationType)
|
||||||
|
localizationContext.setLocalizationLevel(localizationLevel)
|
||||||
|
if level in ['CONFIGURED', 'SITE' ]:
|
||||||
|
localizationContext.setContextName(localizedSite)
|
||||||
|
elif level == 'USER':
|
||||||
|
localizationContext.setContextName(localizationUser)
|
||||||
|
|
||||||
|
# build the utility command
|
||||||
|
cmd.setContext(localizationContext)
|
||||||
|
cmds.append(cmd)
|
||||||
|
|
||||||
|
# add the command(s) to the request
|
||||||
|
req.setCommands(cmds)
|
||||||
|
|
||||||
|
try:
|
||||||
|
serverResponse = thrift.sendRequest(req)
|
||||||
|
except Exception, e:
|
||||||
|
raise RuntimeError, 'Could not retrieve localization file list: ' + str(e)
|
||||||
|
|
||||||
|
return serverResponse
|
||||||
|
|
||||||
|
def _downloadLocalizationFiles(serverResponse, thrift, name):
|
||||||
|
'''
|
||||||
|
@param serverResponse: a list of localization files that will need to
|
||||||
|
be downloaded as well the localization context associated with
|
||||||
|
each file
|
||||||
|
@param thrift: an instance of the thrift client used to communicate
|
||||||
|
with EDEX
|
||||||
|
@param name: the name of the localization file to download. used
|
||||||
|
to verify that .pyc files are not retrieved
|
||||||
|
@return: a list of the localization files that have been downloaded
|
||||||
|
@summary: this function will loop through the server response,
|
||||||
|
execute a function that will retrieve the localization file
|
||||||
|
from the server as bytes, and write the bytes to a temporary
|
||||||
|
file in a dynamically generated location.
|
||||||
|
'''
|
||||||
|
|
||||||
|
lfiles = []
|
||||||
|
|
||||||
|
for response in serverResponse.getResponses():
|
||||||
|
for entry in response.getEntries():
|
||||||
|
filename = entry.getFileName()
|
||||||
|
if filename == name:
|
||||||
|
# create a local copy of the file
|
||||||
|
localizationContext = entry.getContext()
|
||||||
|
bytes = _retrieveFileFromServer(localizationContext, filename, thrift)
|
||||||
|
# create the temporary directory
|
||||||
|
directoryName = tempfile.mkdtemp()
|
||||||
|
filename = os.path.split(name)[1]
|
||||||
|
fileToWrite = os.path.join(directoryName, filename)
|
||||||
|
try:
|
||||||
|
with open(fileToWrite, 'wb') as fileHandle:
|
||||||
|
fileHandle.write(bytes)
|
||||||
|
except:
|
||||||
|
# remove any files that have successfully
|
||||||
|
# been created.
|
||||||
|
_removeTemporaryLocalizationFiles(lfiles)
|
||||||
|
# fail
|
||||||
|
raise IOError('Failed to create a local copy of the localization file: ' + filename)
|
||||||
|
|
||||||
|
lfiles.append(fileToWrite)
|
||||||
|
break
|
||||||
|
|
||||||
|
return lfiles
|
||||||
|
|
||||||
|
def _executeModuleMerge(fileList):
|
||||||
|
'''
|
||||||
|
@param fileList: a list of python modules that will be merged
|
||||||
|
@return: the merged module
|
||||||
|
@summary: this function will run the module merge
|
||||||
|
'''
|
||||||
|
|
||||||
|
# perform the module merge
|
||||||
|
try:
|
||||||
|
themodule = PythonOverriderCore._internalOverride(fileList)
|
||||||
|
finally:
|
||||||
|
_removeTemporaryLocalizationFiles(fileList)
|
||||||
|
|
||||||
|
return themodule
|
||||||
|
|
||||||
|
def _removeTemporaryLocalizationFiles(files):
|
||||||
|
'''
|
||||||
|
@param files: a list files to remove
|
||||||
|
@summary: this function will remove the temporary localization
|
||||||
|
files and directories
|
||||||
|
'''
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
directory = os.path.dirname(file)
|
||||||
|
shutil.rmtree(directory, True)
|
||||||
|
|
||||||
|
def _retrieveFileFromServer(localizationContext, filename, thrift):
|
||||||
|
'''
|
||||||
|
@param localizationContext: the localization context associated
|
||||||
|
with the file that will be downloaded
|
||||||
|
@param filename: the name of the file to download
|
||||||
|
@param thrift: an instance of the thrift client used to communicate
|
||||||
|
with EDEX
|
||||||
|
@return: the bytes associated with the file that was downloaded
|
||||||
|
@summary:
|
||||||
|
'''
|
||||||
|
|
||||||
|
request = LocalizationStreamGetRequest()
|
||||||
|
request.setOffset(0)
|
||||||
|
request.setNumBytes(BUFFER_SIZE)
|
||||||
|
request.setContext(localizationContext)
|
||||||
|
request.setMyContextName(localizationContext.getContextName())
|
||||||
|
request.setFileName(filename)
|
||||||
|
|
||||||
|
bytes = numpy.array([], numpy.int8)
|
||||||
|
finished = False
|
||||||
|
while (not finished):
|
||||||
|
serverResponse = thrift.sendRequest(request)
|
||||||
|
if not isinstance(serverResponse, SuccessfulExecution):
|
||||||
|
message = ""
|
||||||
|
if hasattr(serverResponse, 'getMessage'):
|
||||||
|
message = serverResponse.getMessage()
|
||||||
|
raise RuntimeError(message)
|
||||||
|
serverResponse = serverResponse.getResponse()
|
||||||
|
# serverResponse will be returned as a LocalizationStreamPutRequest
|
||||||
|
# object. we'll use its methods to read back the serialized file
|
||||||
|
# data.
|
||||||
|
# bytes get returned to us as an numpy.ndarray
|
||||||
|
bytes = numpy.append(bytes, serverResponse.getBytes())
|
||||||
|
request.setOffset(request.getOffset() + len(bytes))
|
||||||
|
finished = serverResponse.getEnd()
|
||||||
|
|
||||||
|
return bytes
|
|
@ -206,13 +206,6 @@
|
||||||
version="0.0.0"
|
version="0.0.0"
|
||||||
unpack="false"/>
|
unpack="false"/>
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="com.raytheon.edex.plugin.recco"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
<plugin
|
||||||
id="com.raytheon.edex.plugin.redbook"
|
id="com.raytheon.edex.plugin.redbook"
|
||||||
download-size="0"
|
download-size="0"
|
||||||
|
|
Loading…
Add table
Reference in a new issue