blob: 66a536c69389eef3288c81917385a6233c7f724e [file] [log] [blame]
/*
* 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
}
}