1 /* 2 * Copyright (C) 2010, Marc Strapetz <marc.strapetz@syntevo.com> 3 * and other copyright owners as documented in the project's IP log. 4 * 5 * This program and the accompanying materials are made available 6 * under the terms of the Eclipse Distribution License v1.0 which 7 * accompanies this distribution, is reproduced below, and is 8 * available at http://www.eclipse.org/org/documents/edl-v10.php 9 * 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials provided 22 * with the distribution. 23 * 24 * - Neither the name of the Eclipse Foundation, Inc. nor the 25 * names of its contributors may be used to endorse or promote 26 * products derived from this software without specific prior 27 * written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 */ 43 package org.eclipse.jgit.attributes; 44 45 /** 46 * Represents an attribute. 47 * <p> 48 * According to the man page, an attribute can have the following states: 49 * <ul> 50 * <li>Set - represented by 51 * {@link org.eclipse.jgit.attributes.Attribute.State#SET}</li> 52 * <li>Unset - represented by 53 * {@link org.eclipse.jgit.attributes.Attribute.State#UNSET}</li> 54 * <li>Set to a value - represented by 55 * {@link org.eclipse.jgit.attributes.Attribute.State#CUSTOM}</li> 56 * <li>Unspecified - used to revert an attribute . This is crucial in order to 57 * mark an attribute as unspecified in the attributes map and thus preventing 58 * following (with lower priority) nodes from setting the attribute to a value 59 * at all</li> 60 * </ul> 61 * 62 * @since 3.7 63 */ 64 public final class Attribute { 65 66 /** 67 * The attribute value state 68 * see also https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html 69 */ 70 public static enum State { 71 /** the attribute is set */ 72 SET, 73 74 /** the attribute is unset */ 75 UNSET, 76 77 /** 78 * the attribute appears as if it would not be defined at all 79 * 80 * @since 4.2 81 */ 82 UNSPECIFIED, 83 84 /** the attribute is set to a custom value */ 85 CUSTOM 86 } 87 88 private final String key; 89 private final State state; 90 private final String value; 91 92 /** 93 * Creates a new instance 94 * 95 * @param key 96 * the attribute key. Should not be <code>null</code>. 97 * @param state 98 * the attribute state. It should be either 99 * {@link org.eclipse.jgit.attributes.Attribute.State#SET} or 100 * {@link org.eclipse.jgit.attributes.Attribute.State#UNSET}. In 101 * order to create a custom value attribute prefer the use of 102 * {@link #Attribute(String, String)} constructor. 103 */ 104 public Attribute(String key, State state) { 105 this(key, state, null); 106 } 107 108 private Attribute(String key, State state, String value) { 109 if (key == null) 110 throw new NullPointerException( 111 "The key of an attribute should not be null"); //$NON-NLS-1$ 112 if (state == null) 113 throw new NullPointerException( 114 "The state of an attribute should not be null"); //$NON-NLS-1$ 115 116 this.key = key; 117 this.state = state; 118 this.value = value; 119 } 120 121 /** 122 * Creates a new instance. 123 * 124 * @param key 125 * the attribute key. Should not be <code>null</code>. 126 * @param value 127 * the custom attribute value 128 */ 129 public Attribute(String key, String value) { 130 this(key, State.CUSTOM, value); 131 } 132 133 /** {@inheritDoc} */ 134 @Override 135 public boolean equals(Object obj) { 136 if (this == obj) 137 return true; 138 if (!(obj instanceof Attribute)) 139 return false; 140 Attribute other = (Attribute) obj; 141 if (!key.equals(other.key)) 142 return false; 143 if (state != other.state) 144 return false; 145 if (value == null) { 146 if (other.value != null) 147 return false; 148 } else if (!value.equals(other.value)) 149 return false; 150 return true; 151 } 152 153 /** 154 * Get key 155 * 156 * @return the attribute key (never returns <code>null</code>) 157 */ 158 public String getKey() { 159 return key; 160 } 161 162 /** 163 * Return the state. 164 * 165 * @return the state (never returns <code>null</code>) 166 */ 167 public State getState() { 168 return state; 169 } 170 171 /** 172 * Get value 173 * 174 * @return the attribute value (may be <code>null</code>) 175 */ 176 public String getValue() { 177 return value; 178 } 179 180 /** {@inheritDoc} */ 181 @Override 182 public int hashCode() { 183 final int prime = 31; 184 int result = 1; 185 result = prime * result + key.hashCode(); 186 result = prime * result + state.hashCode(); 187 result = prime * result + ((value == null) ? 0 : value.hashCode()); 188 return result; 189 } 190 191 /** {@inheritDoc} */ 192 @Override 193 public String toString() { 194 switch (state) { 195 case SET: 196 return key; 197 case UNSET: 198 return "-" + key; //$NON-NLS-1$ 199 case UNSPECIFIED: 200 return "!" + key; //$NON-NLS-1$ 201 case CUSTOM: 202 default: 203 return key + "=" + value; //$NON-NLS-1$ 204 } 205 } 206 }