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 {@link State#SET}</li>
51 * <li>Unset - represented by {@link State#UNSET}</li>
52 * <li>Set to a value - represented by {@link State#CUSTOM}</li>
53 * <li>Unspecified - <code>null</code> is used instead of an instance of this
54 * class</li>
55 * </ul>
56 * </p>
57 *
58 * @since 3.7
59 */
60 public final class Attribute {
61
62 /**
63 * The attribute value state
64 */
65 public static enum State {
66 /** the attribute is set */
67 SET,
68
69 /** the attribute is unset */
70 UNSET,
71
72 /** the attribute is set to a custom value */
73 CUSTOM
74 }
75
76 private final String key;
77 private final State state;
78 private final String value;
79
80 /**
81 * Creates a new instance
82 *
83 * @param key
84 * the attribute key. Should not be <code>null</code>.
85 * @param state
86 * the attribute state. It should be either {@link State#SET} or
87 * {@link State#UNSET}. In order to create a custom value
88 * attribute prefer the use of {@link #Attribute(String, String)}
89 * constructor.
90 */
91 public Attribute(String key, State state) {
92 this(key, state, null);
93 }
94
95 private Attribute(String key, State state, String value) {
96 if (key == null)
97 throw new NullPointerException(
98 "The key of an attribute should not be null"); //$NON-NLS-1$
99 if (state == null)
100 throw new NullPointerException(
101 "The state of an attribute should not be null"); //$NON-NLS-1$
102
103 this.key = key;
104 this.state = state;
105 this.value = value;
106 }
107
108 /**
109 * Creates a new instance.
110 *
111 * @param key
112 * the attribute key. Should not be <code>null</code>.
113 * @param value
114 * the custom attribute value
115 */
116 public Attribute(String key, String value) {
117 this(key, State.CUSTOM, value);
118 }
119
120 @Override
121 public boolean equals(Object obj) {
122 if (this == obj)
123 return true;
124 if (!(obj instanceof Attribute))
125 return false;
126 Attribute other = (Attribute) obj;
127 if (!key.equals(other.key))
128 return false;
129 if (state != other.state)
130 return false;
131 if (value == null) {
132 if (other.value != null)
133 return false;
134 } else if (!value.equals(other.value))
135 return false;
136 return true;
137 }
138
139 /**
140 * @return the attribute key (never returns <code>null</code>)
141 */
142 public String getKey() {
143 return key;
144 }
145
146 /**
147 * Returns the state.
148 *
149 * @return the state (never returns <code>null</code>)
150 */
151 public State getState() {
152 return state;
153 }
154
155 /**
156 * @return the attribute value (may be <code>null</code>)
157 */
158 public String getValue() {
159 return value;
160 }
161
162 @Override
163 public int hashCode() {
164 final int prime = 31;
165 int result = 1;
166 result = prime * result + key.hashCode();
167 result = prime * result + state.hashCode();
168 result = prime * result + ((value == null) ? 0 : value.hashCode());
169 return result;
170 }
171
172 @Override
173 public String toString() {
174 switch (state) {
175 case SET:
176 return key;
177 case UNSET:
178 return "-" + key; //$NON-NLS-1$
179 case CUSTOM:
180 default:
181 return key + "=" + value; //$NON-NLS-1$
182 }
183 }
184 }