View Javadoc

1   package eu.medsea.mimeutil.detector;
2   
3   import java.util.HashMap;
4   import java.util.Map;
5   
6   /**
7    * Quote from <a href="http://linux.die.net/man/5/magic">http://linux.die.net/man/5/magic</a>:
8    * <p>
9    * Numeric values may be preceded by a character indicating the operation to be performed.
10   * It may be =, to specify that the value from the file must equal the specified value, &lt;,
11   * to specify that the value from the file must be less than the specified value, &gt;, to
12   * specify that the value from the file must be greater than the specified value, &amp;, to
13   * specify that the value from the file must have set all of the bits that are set in the
14   * specified value, ^, to specify that the value from the file must have clear any of the
15   * bits that are set in the specified value, or ~, the value specified after is negated before
16   * tested. x, to specify that any value will match. If the character is omitted, it is assumed
17   * to be =. For all tests except string and regex, operation ! specifies that the line matches
18   * if the test does not succeed.
19   * </p>
20   * <p>
21   * For string values, the byte string from the file must match the specified byte string. The
22   * operators =, &lt; and &gt; (but not &amp;) can be applied to strings. The length used for
23   * matching is that of the string argument in the magic file. This means that a line can match any
24   * string, and then presumably print that string, by doing &gt;\0 (because all strings are greater
25   * than the null string).
26   * </p>
27   *
28   * @author marco schulze - marco at nightlabs dot de
29   */
30  final class MagicMimeEntryOperation
31  {
32  	private static final Map operationID2operation = new HashMap();
33  
34  	public static final MagicMimeEntryOperation EQUALS = new MagicMimeEntryOperation('=');
35  	public static final MagicMimeEntryOperation LESS_THAN = new MagicMimeEntryOperation('<');
36  	public static final MagicMimeEntryOperation GREATER_THAN = new MagicMimeEntryOperation('>');
37  	public static final MagicMimeEntryOperation AND = new MagicMimeEntryOperation('&');
38  	public static final MagicMimeEntryOperation CLEAR = new MagicMimeEntryOperation('^');
39  	public static final MagicMimeEntryOperation NEGATED = new MagicMimeEntryOperation('~');
40  	public static final MagicMimeEntryOperation ANY = new MagicMimeEntryOperation('x');
41  	public static final MagicMimeEntryOperation NOT_EQUALS = new MagicMimeEntryOperation('!');
42  
43  	public static MagicMimeEntryOperation getOperation(char operationID)
44  	{
45  		Character operationIDCharacter = new Character(operationID);
46  		return (MagicMimeEntryOperation) operationID2operation.get(operationIDCharacter);
47  	}
48  
49  	public static MagicMimeEntryOperation getOperationForStringField(String content)
50  	{
51  		MagicMimeEntryOperation operation = getOperation(content);
52  		// String and regex do only support a subset of the operations => filter.
53  		if (EQUALS.equals(operation) || LESS_THAN.equals(operation) || GREATER_THAN.equals(operation))
54  			return operation;
55  		else
56  			return EQUALS;
57  	}
58  
59  	public static MagicMimeEntryOperation getOperationForNumberField(String content)
60  	{
61  		return getOperation(content);
62  	}
63  
64  	private static MagicMimeEntryOperation getOperation(String content)
65  	{
66  		if (content.length() == 0)
67  			return EQUALS;
68  
69  		MagicMimeEntryOperation operation = getOperation(content.charAt(0));
70  		if (operation == null)
71  			return EQUALS;
72  		else
73  			return operation;
74  	}
75  
76  	private static void registerOperation(MagicMimeEntryOperation operation) {
77  		Character operationIDCharacter = new Character(operation.getOperationID());
78  		if (operationID2operation.containsKey(operationIDCharacter))
79  			throw new IllegalStateException("Duplicate registration of operation " + operationIDCharacter);
80  
81  		operationID2operation.put(operationIDCharacter, operation);
82  	}
83  
84  	private final char operationID;
85  
86  	MagicMimeEntryOperation(char operationID) {
87  		this.operationID = operationID;
88  
89  		registerOperation(this);
90  	}
91  
92  	public int hashCode() {
93  		final int prime = 31;
94  		int result = 1;
95  		result = prime * result + operationID;
96  		return result;
97  	}
98  
99  	public boolean equals(Object obj) {
100 		if (this == obj) return true;
101 		if (obj == null) return false;
102 		if (getClass() != obj.getClass()) return false;
103 		MagicMimeEntryOperation other = (MagicMimeEntryOperation) obj;
104 		return this.operationID == other.operationID;
105 	}
106 
107 	public final char getOperationID() {
108 		return operationID;
109 	}
110 
111 	public String toString() {
112 		return this.getClass().getName() + '[' + operationID + ']';
113 	}
114 }