| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * https://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| package org.apache.ivy.core.module.id; |
| |
| import java.lang.ref.WeakReference; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.WeakHashMap; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.apache.ivy.core.IvyPatternHelper; |
| |
| /** |
| * Identifies a module, without revision information |
| * |
| * @see <a href="package-summary.html">org.apache.ivy.core.module.id</a> |
| */ |
| public class ModuleId implements Comparable<ModuleId> { |
| |
| static final String ENCODE_SEPARATOR = ":#@#:"; |
| |
| private static final Map<ModuleId, WeakReference<ModuleId>> CACHE = new WeakHashMap<>(); |
| |
| /** |
| * Returns a ModuleId for the given organization and module name. |
| * |
| * @param org |
| * the module's organization, can be <code>null</code> |
| * @param name |
| * the module's name, must not be <code>null</code> |
| * @return a ModuleId instance |
| */ |
| public static ModuleId newInstance(String org, String name) { |
| return intern(new ModuleId(org, name)); |
| } |
| |
| /** |
| * Returns an intern instance of a ModuleId equals to the given ModuleId if any, or the given |
| * ModuleId. |
| * <p> |
| * This is useful to reduce the number of instances of ModuleId kept in memory, and thus reduce |
| * memory footprint. |
| * </p> |
| * |
| * @param moduleId |
| * the module id to return |
| * @return a unit instance of the given module id. |
| */ |
| public static ModuleId intern(ModuleId moduleId) { |
| ModuleId r = null; |
| |
| synchronized (CACHE) { |
| WeakReference<ModuleId> ref = CACHE.get(moduleId); |
| if (ref != null) { |
| r = ref.get(); |
| } |
| if (r == null) { |
| r = moduleId; |
| CACHE.put(r, new WeakReference<>(r)); |
| } |
| } |
| |
| return r; |
| } |
| |
| private String organisation; |
| |
| private String name; |
| |
| private int hash; |
| |
| private Map<String, String> attributes = new HashMap<>(); |
| |
| /** |
| * Constructor. |
| * |
| * @param organisation |
| * The organisation which creates the module. |
| * @param name |
| * The name of the module. |
| */ |
| public ModuleId(String organisation, String name) { |
| if (name == null) { |
| throw new IllegalArgumentException("null name not allowed"); |
| } |
| this.organisation = organisation; |
| this.name = name; |
| attributes.put(IvyPatternHelper.ORGANISATION_KEY, organisation); |
| attributes.put(IvyPatternHelper.MODULE_KEY, name); |
| } |
| |
| /** |
| * Returns the name of the module. |
| * |
| * @return The name of the module. |
| */ |
| public String getName() { |
| return name; |
| } |
| |
| /** |
| * Returns the name of the organisation. |
| * |
| * @return The name of the organisation. |
| */ |
| public String getOrganisation() { |
| return organisation; |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (!(obj instanceof ModuleId)) { |
| return false; |
| } |
| ModuleId other = (ModuleId) obj; |
| return (other.organisation == null) |
| ? organisation == null && other.name.equals(name) |
| : other.organisation.equals(organisation) && other.name.equals(name); |
| } |
| |
| @Override |
| public int hashCode() { |
| if (hash == 0) { |
| // CheckStyle:MagicNumber| OFF |
| hash = 31; |
| hash = hash * 13 + (organisation == null ? 0 : organisation.hashCode()); |
| hash = hash * 13 + name.hashCode(); |
| // CheckStyle:MagicNumber| ON |
| } |
| return hash; |
| } |
| |
| @Override |
| public String toString() { |
| return organisation + "#" + name; |
| } |
| |
| public int compareTo(ModuleId that) { |
| int result = organisation.compareTo(that.organisation); |
| if (result == 0) { |
| result = name.compareTo(that.name); |
| } |
| return result; |
| } |
| |
| /** |
| * Returns the encoded String representing this ModuleId. |
| * |
| * @return The ModuleId encoded as String. |
| */ |
| public String encodeToString() { |
| return getOrganisation() + ENCODE_SEPARATOR + getName(); |
| } |
| |
| /** |
| * Returns a Map of all attributes of this module id. The Map keys are attribute names as |
| * Strings, and values are corresponding attribute values (as String too). |
| * |
| * @return A Map instance containing all the attributes and their values. |
| */ |
| public Map<String, String> getAttributes() { |
| return attributes; |
| } |
| |
| /** |
| * Returns a ModuleId |
| * |
| * @param encoded String |
| * @return The new ModuleId. |
| * @throws IllegalArgumentException |
| * If the given String could not be decoded. |
| */ |
| public static ModuleId decode(String encoded) { |
| String[] parts = encoded.split(ENCODE_SEPARATOR); |
| if (parts.length != 2) { |
| throw new IllegalArgumentException("badly encoded module id: '" + encoded + "'"); |
| } |
| return new ModuleId(parts[0], parts[1]); |
| } |
| |
| /** |
| * Pattern to use to matched mid text representation. |
| * |
| * @see #parse(String) |
| */ |
| public static final Pattern MID_PATTERN = Pattern.compile("(" |
| + ModuleRevisionId.STRICT_CHARS_PATTERN + "*)" + "#(" |
| + ModuleRevisionId.STRICT_CHARS_PATTERN + "+)"); |
| |
| /** |
| * Parses the module id text representation and returns it as a {@link ModuleId} instance. |
| * |
| * @param mid |
| * the module id text representation to parse |
| * @return the ModuleId instance corresponding to the representation |
| * @throws IllegalArgumentException |
| * if the given text representation cannot be parsed |
| */ |
| public static ModuleId parse(String mid) { |
| Matcher m = MID_PATTERN.matcher(mid); |
| if (!m.matches()) { |
| throw new IllegalArgumentException( |
| "module text representation do not match expected pattern." + " given mid='" |
| + mid + "' expected form=" + MID_PATTERN.pattern()); |
| } |
| |
| // CheckStyle:MagicNumber| OFF |
| return newInstance(m.group(1), m.group(2)); |
| // CheckStyle:MagicNumber| ON |
| } |
| } |