use of com.zimbra.common.util.Version in project zm-mailbox by Zimbra.
the class AttributeManager method loadAttrs.
private void loadAttrs(File file, Document doc) {
Element root = doc.getRootElement();
if (!root.getName().equals(E_ATTRS)) {
error(null, file, "root tag is not " + E_ATTRS);
return;
}
Map<Integer, String> idsSeen = new HashMap<Integer, String>();
String group = root.attributeValue(A_GROUP);
String groupIdStr = root.attributeValue(A_GROUP_ID);
if (group == null ^ groupIdStr == null) {
error(null, file, A_GROUP + " and " + A_GROUP_ID + " both have to be both specified");
}
int groupId = -1;
if (group != null) {
try {
groupId = Integer.valueOf(groupIdStr);
} catch (NumberFormatException nfe) {
error(null, file, A_GROUP_ID + " is not a number: " + groupIdStr);
}
}
if (groupId == 2) {
error(null, file, A_GROUP_ID + " is not valid (used by ZimbraObjectClass)");
} else if (groupId > 0) {
if (mGroupMap.containsKey(groupId)) {
error(null, file, "duplicate group id: " + groupId);
} else if (mGroupMap.containsValue(group)) {
error(null, file, "duplicate group: " + group);
} else {
mGroupMap.put(groupId, group);
}
}
NEXT_ATTR: for (Iterator iter = root.elementIterator(); iter.hasNext(); ) {
Element eattr = (Element) iter.next();
if (!eattr.getName().equals(E_ATTR)) {
error(null, file, "unknown element: " + eattr.getName());
continue;
}
AttributeCallback callback = null;
AttributeType type = null;
AttributeOrder order = null;
String value = null;
String min = null;
String max = null;
boolean immutable = false;
// boolean ignore = false;
int id = -1;
String parentOid = null;
AttributeCardinality cardinality = null;
Set<AttributeClass> requiredIn = null;
Set<AttributeClass> optionalIn = null;
Set<AttributeFlag> flags = null;
String canonicalName = null;
String name = eattr.attributeValue(A_NAME);
if (name == null) {
error(null, file, "no name specified");
continue;
}
canonicalName = name.toLowerCase();
List<AttributeServerType> requiresRestart = null;
Version deprecatedSinceVer = null;
List<Version> sinceVer = null;
Boolean ephemeral = false;
for (Iterator attrIter = eattr.attributeIterator(); attrIter.hasNext(); ) {
Attribute attr = (Attribute) attrIter.next();
String aname = attr.getName();
if (aname.equals(A_NAME)) {
// nothing to do - already processed
} else if (aname.equals(A_CALLBACK)) {
callback = loadCallback(attr.getValue());
} else if (aname.equals(A_IMMUTABLE)) {
immutable = "1".equals(attr.getValue());
} else if (aname.equals(A_MAX)) {
max = attr.getValue();
} else if (aname.equals(A_MIN)) {
min = attr.getValue();
} else if (aname.equals(A_TYPE)) {
type = AttributeType.getType(attr.getValue());
if (type == null) {
error(name, file, "unknown <attr> type: " + attr.getValue());
continue NEXT_ATTR;
}
} else if (aname.equals(A_VALUE)) {
value = attr.getValue();
} else if (aname.equals(A_PARENT_OID)) {
parentOid = attr.getValue();
if (!parentOid.matches("^\\d+(\\.\\d+)+"))
error(name, file, "invalid parent OID " + parentOid + ": must be an OID");
} else if (aname.equals(A_ID)) {
try {
id = Integer.parseInt(attr.getValue());
if (id < 0) {
error(name, file, "invalid id " + id + ": must be positive");
}
} catch (NumberFormatException nfe) {
error(name, file, aname + " is not a number: " + attr.getValue());
}
} else if (aname.equals(A_CARDINALITY)) {
try {
cardinality = AttributeCardinality.valueOf(attr.getValue());
} catch (IllegalArgumentException iae) {
error(name, file, aname + " is not valid: " + attr.getValue());
}
} else if (aname.equals(A_REQUIRED_IN)) {
requiredIn = parseClasses(name, file, attr.getValue());
} else if (aname.equals(A_OPTIONAL_IN)) {
optionalIn = parseClasses(name, file, attr.getValue());
} else if (aname.equals(A_FLAGS)) {
flags = parseFlags(name, file, attr.getValue());
} else if (aname.equals(A_ORDER)) {
try {
order = AttributeOrder.valueOf(attr.getValue());
} catch (IllegalArgumentException iae) {
error(name, file, aname + " is not valid: " + attr.getValue());
}
} else if (aname.equals(A_REQUIRES_RESTART)) {
requiresRestart = parseRequiresRestart(name, file, attr.getValue());
} else if (aname.equals(A_DEPRECATED_SINCE)) {
String depreSince = attr.getValue();
if (depreSince != null) {
try {
deprecatedSinceVer = new Version(depreSince);
} catch (ServiceException e) {
error(name, file, aname + " is not valid: " + attr.getValue() + " (" + e.getMessage() + ")");
}
}
} else if (aname.equals(A_SINCE)) {
String since = attr.getValue();
if (since != null) {
try {
String[] versions = since.split(",");
sinceVer = new ArrayList<Version>();
for (String verStr : versions) {
sinceVer.add(new Version(verStr.trim()));
}
} catch (ServiceException e) {
error(name, file, aname + " is not valid: " + attr.getValue() + " (" + e.getMessage() + ")");
}
}
} else {
error(name, file, "unknown <attr> attr: " + aname);
}
}
List<String> globalConfigValues = new LinkedList<String>();
// note: init to null instead of empty List
List<String> globalConfigValuesUpgrade = null;
List<String> defaultCOSValues = new LinkedList<String>();
List<String> defaultExternalCOSValues = new LinkedList<String>();
// note: init to null instead of empty List
List<String> defaultCOSValuesUpgrade = null;
String description = null;
String deprecateDesc = null;
for (Iterator elemIter = eattr.elementIterator(); elemIter.hasNext(); ) {
Element elem = (Element) elemIter.next();
if (elem.getName().equals(E_GLOBAL_CONFIG_VALUE)) {
globalConfigValues.add(elem.getText());
} else if (elem.getName().equals(E_GLOBAL_CONFIG_VALUE_UPGRADE)) {
if (globalConfigValuesUpgrade == null)
globalConfigValuesUpgrade = new LinkedList<String>();
globalConfigValuesUpgrade.add(elem.getText());
} else if (elem.getName().equals(E_DEFAULT_COS_VALUE)) {
defaultCOSValues.add(elem.getText());
} else if (elem.getName().equals(E_DEFAULT_EXTERNAL_COS_VALUE)) {
defaultExternalCOSValues.add(elem.getText());
} else if (elem.getName().equals(E_DEFAULT_COS_VALUE_UPGRADE)) {
if (defaultCOSValuesUpgrade == null)
defaultCOSValuesUpgrade = new LinkedList<String>();
defaultCOSValuesUpgrade.add(elem.getText());
} else if (elem.getName().equals(E_DESCRIPTION)) {
if (description != null) {
error(name, file, "more than one " + E_DESCRIPTION);
}
description = elem.getText();
} else if (elem.getName().equals(E_DEPRECATE_DESC)) {
if (deprecateDesc != null) {
error(name, file, "more than one " + E_DEPRECATE_DESC);
}
deprecateDesc = elem.getText();
} else {
error(name, file, "unknown element: " + elem.getName());
}
}
if (deprecatedSinceVer != null && deprecateDesc == null)
error(name, file, "missing element " + E_DEPRECATE_DESC);
else if (deprecatedSinceVer == null && deprecateDesc != null)
error(name, file, "missing attr " + A_DEPRECATED_SINCE);
if (deprecatedSinceVer != null) {
String deprecateInfo = "Deprecated since: " + deprecatedSinceVer.toString() + ". " + deprecateDesc;
if (description == null)
description = deprecateInfo;
else
description = deprecateInfo + ". Orig desc: " + description;
}
// since is required after(inclusive) oid 525 - first attribute in 5.0
if (sinceVer == null && id >= 525) {
error(name, file, "missing since (required after(inclusive) oid 710)");
}
// Check that if id is specified, then cardinality is specified.
if (id > 0 && cardinality == null) {
error(name, file, "cardinality not specified");
}
// Check that if id is specified, then at least one object class is defined
if (id > 0 && (optionalIn != null && optionalIn.isEmpty()) && (requiredIn != null && requiredIn.isEmpty())) {
error(name, file, "atleast one of " + A_REQUIRED_IN + " or " + A_OPTIONAL_IN + " must be specified");
}
// Check that if id is specified, it must be unique
if (id > 0) {
String idForAttr = idsSeen.get(Integer.valueOf(id));
if (idForAttr != null) {
error(name, file, "duplicate id: " + id + " is already used for " + idForAttr);
} else {
idsSeen.put(Integer.valueOf(id), name);
}
}
// Check that if it is COS inheritable it is in account and COS classes
checkFlag(name, file, flags, AttributeFlag.accountInherited, AttributeClass.account, AttributeClass.cos, null, requiredIn, optionalIn);
// Check that if it is COS-domain inheritable it is in account and COS and domain classes
checkFlag(name, file, flags, AttributeFlag.accountCosDomainInherited, AttributeClass.account, AttributeClass.cos, AttributeClass.domain, requiredIn, optionalIn);
// Check that if it is domain inheritable it is in domain and global config
checkFlag(name, file, flags, AttributeFlag.domainInherited, AttributeClass.domain, AttributeClass.globalConfig, null, requiredIn, optionalIn);
// Check that if it is server inheritable it is in server and global config
checkFlag(name, file, flags, AttributeFlag.serverInherited, AttributeClass.server, AttributeClass.globalConfig, null, requiredIn, optionalIn);
// Check that if it is serverPreferAlwaysOn it is in server and alwaysOnCluster
checkFlag(name, file, flags, AttributeFlag.serverPreferAlwaysOn, AttributeClass.server, AttributeClass.alwaysOnCluster, null, requiredIn, optionalIn);
// default value is specified
if (cardinality == AttributeCardinality.single) {
if (globalConfigValues.size() > 1) {
error(name, file, "more than one global config value specified for cardinality " + AttributeCardinality.single);
}
if (defaultCOSValues.size() > 1 || defaultExternalCOSValues.size() > 1) {
error(name, file, "more than one default COS value specified for cardinality " + AttributeCardinality.single);
}
}
checkEphemeralFlags(name, file, flags, min, max, cardinality);
AttributeInfo info = createAttributeInfo(name, id, parentOid, groupId, callback, type, order, value, immutable, min, max, cardinality, requiredIn, optionalIn, flags, globalConfigValues, defaultCOSValues, defaultExternalCOSValues, globalConfigValuesUpgrade, defaultCOSValuesUpgrade, mMinimize ? null : description, requiresRestart, sinceVer, deprecatedSinceVer);
if (mAttrs.get(canonicalName) != null) {
error(name, file, "duplicate definiton");
}
mAttrs.put(canonicalName, info);
if (flags != null) {
for (AttributeFlag flag : flags) {
mFlagToAttrsMap.get(flag).add(name);
if (flag == AttributeFlag.accountCosDomainInherited)
mFlagToAttrsMap.get(AttributeFlag.accountInherited).add(name);
}
}
if (requiredIn != null || optionalIn != null) {
if (requiredIn != null) {
for (AttributeClass klass : requiredIn) {
mClassToAttrsMap.get(klass).add(name);
mClassToLowerCaseAttrsMap.get(klass).add(name.toLowerCase());
}
}
if (optionalIn != null) {
for (AttributeClass klass : optionalIn) {
mClassToAttrsMap.get(klass).add(name);
mClassToLowerCaseAttrsMap.get(klass).add(name.toLowerCase());
}
}
}
if (isBinaryType(type)) {
mBinaryAttrs.add(canonicalName);
} else if (isBinaryTransferType(type)) {
mBinaryTransferAttrs.add(canonicalName);
}
if (flags != null && flags.contains(AttributeFlag.ephemeral)) {
mEphemeralAttrs.put(canonicalName, info);
mEphemeralAttrsSet.add(name);
if (!info.isDynamic()) {
addNonDynamicEphemeralAttr(info);
}
}
}
}
use of com.zimbra.common.util.Version in project zm-mailbox by Zimbra.
the class AttributeManager method versionCheck.
private boolean versionCheck(String attr, String version, boolean in, boolean before) throws ServiceException {
AttributeInfo ai = mAttrs.get(attr.toLowerCase());
if (ai != null) {
List<Version> since = ai.getSince();
if (since == null) {
return true;
} else {
Version current = new Version(version);
boolean good = false;
for (Version sinceVer : since) {
if (current.isSameMinorRelease(sinceVer)) {
// ok same release; just compare
return (before && sinceVer.compare(version) < 0) || (in && sinceVer.compare(version) == 0);
} else if (!current.isLaterMajorMinorRelease(sinceVer)) {
// if it was OK from earlier series then it's OK
return good;
} else {
// current is later major/minor, so check in/before and iterate further
good = (before && sinceVer.compare(version) < 0) || (in && sinceVer.compare(version) == 0);
}
}
return good;
}
} else {
throw AccountServiceException.INVALID_ATTR_NAME("unknown attribute: " + attr, null);
}
}
use of com.zimbra.common.util.Version in project zm-mailbox by Zimbra.
the class TestAttributeManager method setup.
@Before
public void setup() throws ServiceException {
am = new AttributeManager();
Set<AttributeClass> requiredIn = Sets.newHashSet(AttributeClass.account, AttributeClass.alias, AttributeClass.distributionList, AttributeClass.domain, AttributeClass.server, AttributeClass.alwaysOnCluster, AttributeClass.ucService, AttributeClass.cos, AttributeClass.xmppComponent, AttributeClass.group, AttributeClass.groupDynamicUnit, AttributeClass.groupStaticUnit);
Set<AttributeFlag> flags = Sets.newHashSet(AttributeFlag.accountInfo);
AttributeInfo ai = new AttributeInfo("zimbraId", 1, null, 0, null, AttributeType.TYPE_ID, null, "", true, null, null, AttributeCardinality.single, requiredIn, null, flags, null, null, null, null, null, "Zimbra Systems Unique ID", null, null, null);
am.addAttribute(ai);
requiredIn = null;
Set<AttributeClass> optionalIn = Sets.newHashSet(AttributeClass.domain, AttributeClass.globalConfig);
flags = Sets.newHashSet(AttributeFlag.domainInherited);
List<Version> since = Lists.newArrayList(new Version("5.0.10"));
ai = new AttributeInfo("zimbraZimletDomainAvailableZimlets", 710, null, 0, new AvailableZimlets(), AttributeType.TYPE_STRING, null, "", false, null, "256", AttributeCardinality.multi, requiredIn, optionalIn, flags, null, null, null, null, null, "List of Zimlets available to this domain.", null, since, null);
am.addAttribute(ai);
requiredIn = null;
optionalIn = null;
flags = null;
since = Lists.newArrayList(new Version("8.0.8"), new Version("8.5.1"));
ai = new AttributeInfo(ATTR_TWO_SINCE, 99996, null, 0, null, AttributeType.TYPE_STRING, null, "", false, null, null, AttributeCardinality.multi, requiredIn, optionalIn, flags, null, null, null, null, null, "test two since", null, since, null);
am.addAttribute(ai);
;
since = Lists.newArrayList(new Version("9.0.0"), new Version("8.0.8"), new Version("7.2.8"), new Version("8.5.2"));
// out of order intentionally; attributeinfo class should handle that so we don't have bugs if someone no-brains this
ai = new AttributeInfo(ATTR_MULTI_SINCE, 99997, null, 0, null, AttributeType.TYPE_STRING, null, "", false, null, null, AttributeCardinality.multi, requiredIn, optionalIn, flags, null, null, null, null, null, "test multi since", null, since, null);
am.addAttribute(ai);
;
since = Lists.newArrayList(new Version(Version.FUTURE));
ai = new AttributeInfo(ATTR_FUTURE, 99998, null, 0, null, AttributeType.TYPE_STRING, null, "", false, null, null, AttributeCardinality.single, requiredIn, optionalIn, flags, null, null, null, null, null, "test future", null, since, null);
am.addAttribute(ai);
}
use of com.zimbra.common.util.Version in project zm-mailbox by Zimbra.
the class BUG_27075 method doEntry.
private void doEntry(ZLdapContext zlc, Entry entry, String entryName, AttributeClass klass) throws ServiceException {
printer.println();
printer.println("------------------------------");
printer.println("Upgrading " + entryName + ": ");
AttributeManager am = AttributeManager.getInstance();
Set<String> attrs = am.getAttrsInClass(klass);
Map<String, Object> attrValues = new HashMap<String, Object>();
for (String attr : attrs) {
AttributeInfo ai = am.getAttributeInfo(attr);
if (ai == null)
continue;
List<Version> attrVersion = ai.getSince();
if (needsUpgrade(am, attr)) {
if (verbose) {
printer.println("");
printer.println("Checking " + entryName + " attribute: " + attr + attrVersion);
}
String curVal = entry.getAttr(attr);
if (curVal != null) {
// already has a value, skip it
if (verbose) {
if (ai.getCardinality() == AttributeCardinality.multi)
curVal = formatMultiValue(entry.getMultiAttrSet(attr));
printer.println(" skipping - already has value: " + curVal);
}
continue;
}
/*
* use the upgrade values if set, otherwise use the default values
*
* Note, we support the case when we need to leave the value unset
* on upgrades, but set a value on new installs. In AttributeManager,
* if <globalConfigValueUpgrade> or <defaultCOSValueUpgrade> element
* is present but does not have a value, AttributeInfo.getGlobalConfigValuesUpgrade()/
* getDefaultCosValuesUpgrade() will return an empty List. If the upgrade
* element is not present, the two methods will return null. We check
* null here and if it is null then use the same default value for new
* installs.
*/
List<String> values = null;
if (klass == AttributeClass.globalConfig) {
values = ai.getGlobalConfigValuesUpgrade();
if (values == null)
values = ai.getGlobalConfigValues();
} else if (klass == AttributeClass.cos) {
values = ai.getDefaultCosValuesUpgrade();
if (values == null)
values = ai.getDefaultCosValues();
} else {
printer.println("Internal error: invalid attribute class " + klass.name());
return;
}
if (values == null || values.size() == 0) {
if (verbose) {
printer.println(" skipping - does not have a default value");
}
continue;
}
attrValues.clear();
if (ai.getCardinality() != AttributeCardinality.multi) {
printer.println(" setting " + entryName + " attribute " + attr + attrVersion + " to: " + values.get(0));
attrValues.put(attr, values.get(0));
} else {
printer.println(" setting " + entryName + " attribute " + attr + attrVersion + " to: " + formatMultiValue(values));
attrValues.put(attr, values.toArray(new String[0]));
}
try {
modifyAttrs(zlc, entry, attrValues);
} catch (ServiceException e) {
// log the exception and continue
printer.println("Caught ServiceException while modifying " + entryName + " attribute " + attr);
printer.printStackTrace(e);
}
}
}
}
use of com.zimbra.common.util.Version in project zm-mailbox by Zimbra.
the class DocumentHandler method zimbraConnectorClientVersion.
protected static Pair<String, Version> zimbraConnectorClientVersion(ZimbraSoapContext zsc) {
final String UA_ZCO = "ZimbraConnectorForOutlook";
final String UA_ZCB = "ZimbraConnectorForBES";
final String UA_MIGRATION = "ZimbraMigration";
String ua = zsc.getUserAgent();
// MIGRATION: ZimbraMigration/8.0.0.x (where x is latest build number)
if (ua != null) {
String[] parts = ua.split("/");
if (parts.length == 2) {
String app = parts[0];
String version = parts[1];
if (UA_ZCO.equalsIgnoreCase(app) || UA_ZCB.equalsIgnoreCase(app) || UA_MIGRATION.equalsIgnoreCase(app)) {
try {
return new Pair<String, Version>(app, new Version(version, false));
} catch (ServiceException e) {
ZimbraLog.soap.debug("unable to parse zimbra connector client version", e);
}
}
}
}
return null;
}
Aggregations