View Javadoc

1   package net.sf.jpkgmk.prototype;
2   
3   import java.util.Arrays;
4   
5   import net.sf.jpkgmk.util.StringUtil;
6   import net.sf.jpkgmk.util.StringUtil.KeyValuePair;
7   
8   /**
9    * Typesafe enumeration CommandType
10   * @author gommma (gommma AT users.sourceforge.net)
11   * @author Last changed by: $Author: gommma $
12   * @version $Revision: 2 $ $Date: 2008-08-20 21:14:19 +0200 (Mi, 20 Aug 2008) $
13   * @since 1.0
14   */
15  public class CommandType implements java.io.Serializable {
16      /**
17  	 * 
18  	 */
19  	private static final long serialVersionUID = 1L;
20  
21  	public static final CommandType SEARCH = new CommandType(1, "search", new CommandTypeSearchParser(), "search - Specifies a list of directories (separated by white space) to search for when looking for file contents on the host  machine. The base  name  of the path field is appended to each directory in the ordered list until the file is located. Searches are not recursive.");
22      public static final CommandType INCLUDE = new CommandType(2, "include", new CommandTypeIncludeParser(), "include - Specifies a pathname which points to another prototype file to include. Note that search requests do not span include files.");
23      public static final CommandType DEFAULT = new CommandType(3, "default", new CommandTypeDefaultParser(), "default - Specifies a list of attributes (mode, owner, and  group) to be used by default if attribute information is not provided for  prototype entries which require the information. The defaults do not apply to entries in include prototype files.");
24      public static final CommandType PARAM_VALUE = new CommandType(4, null, new CommandTypeParamValueParser(), "param=value - Places the indicated parameter in the current environment. Spans to subsequent included prototype files.");
25      public static CommandType[] VALUES = new CommandType[] {
26          SEARCH, 
27          INCLUDE, 
28          DEFAULT, 
29          PARAM_VALUE
30      };
31  
32      private int id;
33      private String idName;
34      private String description;
35      private CommandTypeParser parser;
36  
37      
38      private CommandType(int id, String idName, CommandTypeParser typeParser, String description) {
39          this.id = id;
40          this.idName = idName;
41          this.parser = typeParser;
42          this.description = description;
43      }
44  
45      /**
46       * @return Returns the unique name of this command type to be used for writing it into the prototype file
47       */
48      public String getIdName()
49      {
50      	return this.idName;
51      }
52      
53      /**
54       * Returns true if the given command name matches this command.
55       * @param commandName
56       * @return
57       */
58      public boolean matches(String commandName)
59      {
60      	if(this.idName != null) {
61      		return this.idName.equals(commandName);
62      	}
63      	else {
64      		return (commandName == null);
65      	}
66      }
67      
68  	public CommandTypeParser getParser() {
69  		return this.parser;
70  	}
71  
72      
73      /**
74       * Resolves the command type by the surrogate id
75       * @param searchedId
76       * @return Returns the command for the given ID or null if it was not found.
77       */
78      public static CommandType findType(int searchedId) {
79          for(int i=0; i<VALUES.length; i++) {
80              if(VALUES[i].id == searchedId)
81                  return VALUES[i];
82          }
83          // The type was not found. Return null.
84          return null;
85      }
86  
87      /**
88       * Resolves the command type by the given name. If no command key matches we
89       * assume that it is a "Param=value" command and return {@link #PARAM_VALUE}.
90       * @param commandName The name of the command to be found, e.g. "search"
91       * @return The found command or {@link #PARAM_VALUE} if it could not be resolved.
92       */
93      public static CommandType findTypeByName(String commandName) {
94          for(int i=0; i<VALUES.length; i++) {
95              if(VALUES[i].matches(commandName)) {
96              	return VALUES[i];
97              }
98          }
99          // The type was not found. It must be a "param=value" command.
100         return CommandType.PARAM_VALUE;
101     }
102 
103     // See http://www.javaworld.com/javaworld/javatips/jw-javatip122.html?page=2 for reasons why to implement readResolve
104     private Object readResolve() throws java.io.ObjectStreamException {
105         return findType(this.id);
106     }
107 
108 	@Override
109 	public int hashCode() {
110 		final int prime = 31;
111 		int result = 1;
112 		result = prime * result + id;
113 		return result;
114 	}
115 
116 	@Override
117 	public boolean equals(Object obj) {
118 		if (this == obj)
119 			return true;
120 		if (obj == null)
121 			return false;
122 		if (this.getClass() != obj.getClass())
123 			return false;
124 		final CommandType other = (CommandType) obj;
125 		if (id != other.id)
126 			return false;
127 		return true;
128 	}
129 
130     @Override
131 	public String toString() {
132     	StringBuffer sb = new StringBuffer();
133     	sb.append(this.getClass().getName()).append("[");
134     	sb.append("id=").append(id);
135     	sb.append(",idName=").append(idName);
136     	sb.append(",description=").append(StringUtil.truncateToMaxLength(this.description, 20));
137     	sb.append("]");
138     	return sb.toString();
139     }
140 
141     
142     
143     
144     public static interface CommandTypeParser
145     {
146     	public PrototypeEntryCommand parse(String[]commandTypeEntries);
147     }
148     
149     public static class CommandTypeSearchParser implements CommandTypeParser
150     {
151 
152 		public PrototypeEntryCommand parse(String[] commandTypeEntries) {
153 			String searchString = commandTypeEntries[0];
154 			// Just a sanity check
155 			if(!CommandType.SEARCH.matches(searchString)) {
156 				throw new IllegalArgumentException("The given array is wrong. First element '" + searchString + "' must be a '" + CommandType.SEARCH + "'. Array=" + Arrays.asList(commandTypeEntries));
157 			}
158 
159 			String[] searchPaths = new String[commandTypeEntries.length-1];
160 			System.arraycopy(commandTypeEntries, 1, searchPaths, 0, searchPaths.length);
161 			
162 			PrototypeEntryCommand prototypeEntry = new PrototypeEntryCommandSearch(searchPaths);
163 			return prototypeEntry;
164 		}
165     	
166     }
167     
168     public static class CommandTypeIncludeParser implements CommandTypeParser
169     {
170 
171 		public PrototypeEntryCommand parse(String[] commandTypeEntries) {
172 			String includeString = commandTypeEntries[0];
173 			// Just a sanity check
174 			if(!CommandType.INCLUDE.matches(includeString)) {
175 				throw new IllegalArgumentException("The given array is wrong. First element '" + includeString + "' must be a '" + CommandType.INCLUDE + "'. Array=" + Arrays.asList(commandTypeEntries));
176 			}
177 
178 			// Merge all entries again, but exclude the first one which is the "include" string
179 			String includePath = StringUtil.createString(commandTypeEntries, 1, PrototypeParser.DEFAULT_LINE_DELIMITER);
180 			
181 			PrototypeEntryCommand entry = new PrototypeEntryCommandInclude(includePath);
182 			return entry;
183 		}
184     	
185     }
186 
187     public static class CommandTypeDefaultParser implements CommandTypeParser
188     {
189 
190 		public PrototypeEntryCommand parse(String[] commandTypeEntries) {
191 			String defaultString = commandTypeEntries[0];
192 			// Just a sanity check
193 			if(!CommandType.DEFAULT.matches(defaultString)) {
194 				throw new IllegalArgumentException("The given array is wrong. First element '" + defaultString + "' must be a '" + CommandType.DEFAULT + "'. Array=" + Arrays.asList(commandTypeEntries));
195 			}
196 			
197 			String mode = commandTypeEntries[1];
198 			String owner = commandTypeEntries[2];
199 			String group = commandTypeEntries[3];
200 			PrototypeEntryCommand entry = new PrototypeEntryCommandDefault(mode, owner, group);
201 			return entry;
202 		}
203     	
204     }
205 
206     public static class CommandTypeParamValueParser implements CommandTypeParser
207     {
208 		public PrototypeEntryCommand parse(String[] commandTypeEntries) {
209 			
210 			// Merge all entries again, but exclude the first one which is the "include" string
211 			String paramValueString = StringUtil.createString(commandTypeEntries, PrototypeParser.DEFAULT_LINE_DELIMITER);
212 
213 			KeyValuePair keyValue = StringUtil.resolveKeyValue(paramValueString);
214 			String entryPath = keyValue.getKey();
215 			String entryPathSource = keyValue.getValue();
216 			
217 			PrototypeEntryCommand command = new PrototypeEntryCommandVariable(entryPath, entryPathSource);
218 			return command;
219 		}
220     	
221     }
222 
223 }