001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.metadata; 020 021import java.io.File; 022import java.nio.file.Path; 023import java.util.Collections; 024import java.util.HashMap; 025import java.util.Map; 026import java.util.Objects; 027 028/** 029 * A skeleton class for metadata. 030 */ 031public abstract class AbstractMetadata implements Metadata { 032 033 /** 034 * Constructor for subclasses. 035 */ 036 public AbstractMetadata() {} 037 038 private Metadata newInstance(Map<String, String> properties, Path path) { 039 return new DefaultMetadata( 040 getGroupId(), getArtifactId(), getVersion(), getType(), getNature(), path, properties); 041 } 042 043 @Deprecated 044 @Override 045 public Metadata setFile(File file) { 046 File current = getFile(); 047 if (Objects.equals(current, file)) { 048 return this; 049 } 050 return newInstance(getProperties(), file != null ? file.toPath() : null); 051 } 052 053 @Override 054 public Metadata setPath(Path path) { 055 Path current = getPath(); 056 if (Objects.equals(current, path)) { 057 return this; 058 } 059 return newInstance(getProperties(), path); 060 } 061 062 @Override 063 public Metadata setProperties(Map<String, String> properties) { 064 Map<String, String> current = getProperties(); 065 if (current.equals(properties) || (properties == null && current.isEmpty())) { 066 return this; 067 } 068 return newInstance(copyProperties(properties), getPath()); 069 } 070 071 @Override 072 public String getProperty(String key, String defaultValue) { 073 String value = getProperties().get(key); 074 return (value != null) ? value : defaultValue; 075 } 076 077 /** 078 * Copies the specified metadata properties. This utility method should be used when creating new metadata instances 079 * with caller-supplied properties. 080 * 081 * @param properties The properties to copy, may be {@code null}. 082 * @return The copied and read-only properties, never {@code null}. 083 */ 084 protected static Map<String, String> copyProperties(Map<String, String> properties) { 085 if (properties != null && !properties.isEmpty()) { 086 return Collections.unmodifiableMap(new HashMap<>(properties)); 087 } else { 088 return Collections.emptyMap(); 089 } 090 } 091 092 @Override 093 public String toString() { 094 StringBuilder buffer = new StringBuilder(128); 095 if (!getGroupId().isEmpty()) { 096 buffer.append(getGroupId()); 097 } 098 if (!getArtifactId().isEmpty()) { 099 buffer.append(':').append(getArtifactId()); 100 } 101 if (!getVersion().isEmpty()) { 102 buffer.append(':').append(getVersion()); 103 } 104 buffer.append('/').append(getType()); 105 return buffer.toString(); 106 } 107 108 /** 109 * Compares this metadata with the specified object. 110 * 111 * @param obj The object to compare this metadata against, may be {@code null}. 112 * @return {@code true} if and only if the specified object is another {@link Metadata} with equal coordinates, 113 * type, nature, properties and file, {@code false} otherwise. 114 */ 115 @Override 116 public boolean equals(Object obj) { 117 if (obj == this) { 118 return true; 119 } else if (!(obj instanceof Metadata)) { 120 return false; 121 } 122 123 Metadata that = (Metadata) obj; 124 125 return Objects.equals(getArtifactId(), that.getArtifactId()) 126 && Objects.equals(getGroupId(), that.getGroupId()) 127 && Objects.equals(getVersion(), that.getVersion()) 128 && Objects.equals(getType(), that.getType()) 129 && Objects.equals(getNature(), that.getNature()) 130 && Objects.equals(getPath(), that.getPath()) 131 && Objects.equals(getProperties(), that.getProperties()); 132 } 133 134 /** 135 * Returns a hash code for this metadata. 136 * 137 * @return A hash code for the metadata. 138 */ 139 @Override 140 public int hashCode() { 141 int hash = 17; 142 hash = hash * 31 + getGroupId().hashCode(); 143 hash = hash * 31 + getArtifactId().hashCode(); 144 hash = hash * 31 + getType().hashCode(); 145 hash = hash * 31 + getNature().hashCode(); 146 hash = hash * 31 + getVersion().hashCode(); 147 hash = hash * 31 + hash(getPath()); 148 return hash; 149 } 150 151 private static int hash(Object obj) { 152 return (obj != null) ? obj.hashCode() : 0; 153 } 154}