Search in sources :

Example 1 with Version

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);
            }
        }
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) Attribute(org.dom4j.Attribute) Element(org.dom4j.Element) ArrayList(java.util.ArrayList) Version(com.zimbra.common.util.Version) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) LinkedList(java.util.LinkedList) ServiceException(com.zimbra.common.service.ServiceException)

Example 2 with Version

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);
    }
}
Also used : Version(com.zimbra.common.util.Version)

Example 3 with Version

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);
}
Also used : Version(com.zimbra.common.util.Version) AvailableZimlets(com.zimbra.cs.account.callback.AvailableZimlets) Before(org.junit.Before)

Example 4 with Version

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);
            }
        }
    }
}
Also used : AttributeInfo(com.zimbra.cs.account.AttributeInfo) AttributeManager(com.zimbra.cs.account.AttributeManager) ServiceException(com.zimbra.common.service.ServiceException) HashMap(java.util.HashMap) Version(com.zimbra.common.util.Version)

Example 5 with Version

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;
}
Also used : AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) Version(com.zimbra.common.util.Version) Pair(com.zimbra.common.util.Pair)

Aggregations

Version (com.zimbra.common.util.Version)5 ServiceException (com.zimbra.common.service.ServiceException)3 HashMap (java.util.HashMap)2 Pair (com.zimbra.common.util.Pair)1 AccountServiceException (com.zimbra.cs.account.AccountServiceException)1 AttributeInfo (com.zimbra.cs.account.AttributeInfo)1 AttributeManager (com.zimbra.cs.account.AttributeManager)1 AvailableZimlets (com.zimbra.cs.account.callback.AvailableZimlets)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Set (java.util.Set)1 Attribute (org.dom4j.Attribute)1 Element (org.dom4j.Element)1 Before (org.junit.Before)1