/** @see XMPSchemaRegistry#registerNamespace(String, String) */ public synchronized String registerNamespace(String namespaceURI, String suggestedPrefix) throws XMPException { ParameterAsserts.assertSchemaNS(namespaceURI); ParameterAsserts.assertPrefix(suggestedPrefix); if (suggestedPrefix.charAt(suggestedPrefix.length() - 1) != ':') { suggestedPrefix += ':'; } if (!Utils.isXMLNameNS(suggestedPrefix.substring(0, suggestedPrefix.length() - 1))) { throw new XMPException("The prefix is a bad XML name", XMPError.BADXML); } String registeredPrefix = (String) namespaceToPrefixMap.get(namespaceURI); String registeredNS = (String) prefixToNamespaceMap.get(suggestedPrefix); if (registeredPrefix != null) { // Return the actual prefix return registeredPrefix; } else { if (registeredNS != null) { // the namespace is new, but the prefix is already engaged, // we generate a new prefix out of the suggested String generatedPrefix = suggestedPrefix; for (int i = 1; prefixToNamespaceMap.containsKey(generatedPrefix); i++) { generatedPrefix = suggestedPrefix.substring(0, suggestedPrefix.length() - 1) + "_" + i + "_:"; } suggestedPrefix = generatedPrefix; } prefixToNamespaceMap.put(suggestedPrefix, namespaceURI); namespaceToPrefixMap.put(namespaceURI, suggestedPrefix); // Return the suggested prefix return suggestedPrefix; } }
/** * Associates an alias name with an actual name. * * <p>Define a alias mapping from one namespace/property to another. Both property names must be * simple names. An alias can be a direct mapping, where the alias and actual have the same data * type. It is also possible to map a simple alias to an item in an array. This can either be to * the first item in the array, or to the 'x-default' item in an alt-text array. Multiple alias * names may map to the same actual, as long as the forms match. It is a no-op to reregister an * alias in an identical fashion. Note: This method is not locking because only called by * registerStandardAliases which is only called by the constructor. Note2: The method is only * package-private so that it can be tested with unittests * * @param aliasNS The namespace URI for the alias. Must not be null or the empty string. * @param aliasProp The name of the alias. Must be a simple name, not null or the empty string and * not a general path expression. * @param actualNS The namespace URI for the actual. Must not be null or the empty string. * @param actualProp The name of the actual. Must be a simple name, not null or the empty string * and not a general path expression. * @param aliasForm Provides options for aliases for simple aliases to array items. This is needed * to know what kind of array to create if set for the first time via the simple alias. Pass * <code>XMP_NoOptions</code>, the default value, for all direct aliases regardless of whether * the actual data type is an array or not (see {@link AliasOptions}). * @throws XMPException for inconsistant aliases. */ synchronized void registerAlias( String aliasNS, String aliasProp, final String actualNS, final String actualProp, final AliasOptions aliasForm) throws XMPException { ParameterAsserts.assertSchemaNS(aliasNS); ParameterAsserts.assertPropName(aliasProp); ParameterAsserts.assertSchemaNS(actualNS); ParameterAsserts.assertPropName(actualProp); // Fix the alias options final AliasOptions aliasOpts = aliasForm != null ? new AliasOptions( XMPNodeUtils.verifySetOptions(aliasForm.toPropertyOptions(), null).getOptions()) : new AliasOptions(); if (p.matcher(aliasProp).find() || p.matcher(actualProp).find()) { throw new XMPException("Alias and actual property names must be simple", XMPError.BADXPATH); } // check if both namespaces are registered final String aliasPrefix = getNamespacePrefix(aliasNS); final String actualPrefix = getNamespacePrefix(actualNS); if (aliasPrefix == null) { throw new XMPException("Alias namespace is not registered", XMPError.BADSCHEMA); } else if (actualPrefix == null) { throw new XMPException("Actual namespace is not registered", XMPError.BADSCHEMA); } String key = aliasPrefix + aliasProp; // check if alias is already existing if (aliasMap.containsKey(key)) { throw new XMPException("Alias is already existing", XMPError.BADPARAM); } else if (aliasMap.containsKey(actualPrefix + actualProp)) { throw new XMPException( "Actual property is already an alias, use the base property", XMPError.BADPARAM); } XMPAliasInfo aliasInfo = new XMPAliasInfo() { /** @see XMPAliasInfo#getNamespace() */ public String getNamespace() { return actualNS; } /** @see XMPAliasInfo#getPrefix() */ public String getPrefix() { return actualPrefix; } /** @see XMPAliasInfo#getPropName() */ public String getPropName() { return actualProp; } /** @see XMPAliasInfo#getAliasForm() */ public AliasOptions getAliasForm() { return aliasOpts; } public String toString() { return actualPrefix + actualProp + " NS(" + actualNS + "), FORM (" + getAliasForm() + ")"; } }; aliasMap.put(key, aliasInfo); }