001: /*
002: * Gruntspud
003: *
004: * Copyright (C) 2002 Brett Smith.
005: *
006: * Written by: Brett Smith <t_magicthize@users.sourceforge.net>
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public License
010: * as published by the Free Software Foundation; either version 2 of
011: * the License, or (at your option) any later version.
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Library General Public License for more details.
016: *
017: * You should have received a copy of the GNU Library General Public
018: * License along with this program; if not, write to the Free Software
019: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
020: */
021:
022: package gruntspud.file;
023:
024: import java.io.*;
025: import java.util.*;
026:
027: import org.netbeans.lib.cvsclient.file.FileUtils;
028: import org.netbeans.lib.cvsclient.util.*;
029:
030: public class GruntspudFileMode {
031:
032: // Supporting classes
033:
034: public static FileModeType USER_FILE_MODE_TYPE = new FileModeType(
035: 'u');
036: public static FileModeType GROUP_FILE_MODE_TYPE = new FileModeType(
037: 'g');
038: public static FileModeType OTHER_FILE_MODE_TYPE = new FileModeType(
039: 'o');
040:
041: public static FileModePermission READ_PERMISSION = new FileModePermission(
042: 'r');
043: public static FileModePermission WRITE_PERMISSION = new FileModePermission(
044: 'w');
045: public static FileModePermission EXECUTE_PERMISSION = new FileModePermission(
046: 'x');
047:
048: /**
049: * The underlying file
050: */
051: private File file;
052:
053: /**
054: * Construct a new file mode with the default permissions (u=rw,g=r,o=r)
055: */
056: public GruntspudFileMode() {
057: this (true);
058: }
059:
060: /**
061: * Construct a new file mode
062: *
063: * @param file file
064: */
065: public GruntspudFileMode(File file) {
066: GruntspudFileMode mode = getFileModeForFile(file);
067: this .permissions = mode.permissions;
068: }
069:
070: /**
071: * Construct a new file mode with the default permissions (u=rw,g=r,o=r)
072: */
073: private GruntspudFileMode(boolean copyFromDefault) {
074: permissions = new HashMap();
075: if (copyFromDefault) {
076: setPermission(USER_FILE_MODE_TYPE, getDefaultFileMode()
077: .getPermission(USER_FILE_MODE_TYPE));
078: setPermission(GROUP_FILE_MODE_TYPE, getDefaultFileMode()
079: .getPermission(GROUP_FILE_MODE_TYPE));
080: setPermission(OTHER_FILE_MODE_TYPE, getDefaultFileMode()
081: .getPermission(OTHER_FILE_MODE_TYPE));
082: }
083: }
084:
085: /**
086: * Get the permissions for a given file mode type
087: *
088: * @param fileModeType file mode type
089: * @return permissions
090: */
091: public FileModePermission[] getPermission(FileModeType type) {
092: return (FileModePermission[]) permissions.get(type);
093: }
094:
095: /**
096: * Determine if a <code>FileMode</code> has a particular permission set
097: *
098: * @param fileModeType
099: * @param fileModePermission
100: * @return <code>true</code> if file has permission
101: */
102: public boolean hasPermission(FileModeType fileModeType,
103: FileModePermission fileModePermission) {
104: FileModePermission[] p = (FileModePermission[]) permissions
105: .get(fileModeType);
106: for (int i = 0; i < p.length; i++)
107: if (p[i] == fileModePermission)
108: return true;
109: return false;
110: }
111:
112: public Object clone() throws CloneNotSupportedException {
113: return super .clone();
114: }
115:
116: /**
117: * Return a file mode type given its mnemonic
118: *
119: * @param fileModeType
120: * @param fileModePermission
121: */
122: public static FileModeType getFileModeTypeForMnemonic(char mnemonic) {
123: if (mnemonic == 'u')
124: return USER_FILE_MODE_TYPE;
125: else if (mnemonic == 'g')
126: return GROUP_FILE_MODE_TYPE;
127: else
128: return OTHER_FILE_MODE_TYPE;
129: }
130:
131: /**
132: * Remove a permission.
133: *
134: * @param fileModeType
135: * @param fileModePermission
136: */
137: public void removePermission(FileModeType fileModeType,
138: FileModePermission fileModePermission) {
139: FileModePermission[] p = (FileModePermission[]) permissions
140: .get(fileModeType);
141: Vector v = new Vector();
142: for (int i = 0; i < p.length; i++)
143: if (p[i] != fileModePermission)
144: v.addElement(p[i]);
145: FileModePermission[] p2 = new FileModePermission[v.size()];
146: v.copyInto(p2);
147: setPermission(fileModeType, p2);
148: }
149:
150: /**
151: * Set the permissions for a given <code>FileModeType</code>.
152: *
153: * @param fileModeType file mode type
154: * @param fileModePermission file mode permission
155: */
156: public void setPermission(FileModeType fileModeType,
157: FileModePermission[] fileModePermission) {
158: permissions.put(fileModeType, fileModePermission);
159: }
160:
161: /**
162: * Returns a CVS-compatible file mode string
163: */
164: public String toString() {
165: StringBuffer buf = new StringBuffer();
166: buf.append(USER_FILE_MODE_TYPE.fileModeTypeMnemonic);
167: buf.append('=');
168: buf
169: .append(permissionsToString((FileModePermission[]) permissions
170: .get(USER_FILE_MODE_TYPE)));
171: buf.append(',');
172: buf.append(GROUP_FILE_MODE_TYPE.fileModeTypeMnemonic);
173: buf.append('=');
174: buf
175: .append(permissionsToString((FileModePermission[]) permissions
176: .get(GROUP_FILE_MODE_TYPE)));
177: buf.append(',');
178: buf.append(OTHER_FILE_MODE_TYPE.fileModeTypeMnemonic);
179: buf.append('=');
180: buf
181: .append(permissionsToString((FileModePermission[]) permissions
182: .get(OTHER_FILE_MODE_TYPE)));
183: return buf.toString();
184: }
185:
186: /**
187: * Return an array of <code>FileModePermission</code>'s given a string.
188: * Each character in the string will be examined for the mnemonic of the
189: * three know permission read,write and execute
190: *
191: * @param string representation of the permission
192: * @return array of permission object
193: */
194: public static FileModePermission[] getPermissionsForString(String s) {
195: Vector v = new Vector();
196: for (int i = 0; i < s.length(); i++) {
197: if (s.charAt(i) == READ_PERMISSION.fileModePermissionMnemonic)
198: v.addElement(READ_PERMISSION);
199: else if (s.charAt(i) == WRITE_PERMISSION.fileModePermissionMnemonic)
200: v.addElement(WRITE_PERMISSION);
201: else if (s.charAt(i) == EXECUTE_PERMISSION.fileModePermissionMnemonic)
202: v.addElement(EXECUTE_PERMISSION);
203: }
204: FileModePermission[] a = new FileModePermission[v.size()];
205: v.copyInto(a);
206: return a;
207: }
208:
209: /**
210: * Utility to set a file given a <code>FileMode</code> specify what
211: * permissions should be set
212: *
213: * @param fileMode file mode object
214: * @param file file to set mode on
215: * @throws IOException
216: */
217: public static void setFileModeForFile(GruntspudFileMode fileMode,
218: File file) {
219: boolean doneWithFileModeHandler = false;
220: // Try the file mode handler
221: try {
222: if (GruntspudFileUtils.getFileModeHandler() != null) {
223: GruntspudFileUtils.getFileModeHandler().setFileMode(
224: file, fileMode);
225: doneWithFileModeHandler = true;
226: }
227: } catch (IOException ioe) {
228: BugLog.getInstance().bug(
229: "**WARNING** Registered FileModeHandler "
230: + "could not set the mode "
231: + fileMode.toString() + " for file "
232: + file.getAbsolutePath());
233: BugLog.getInstance().showException(ioe);
234: }
235: // Try the read only handler
236: if (!doneWithFileModeHandler) {
237: boolean doneWithReadOnlyHandler = false;
238: try {
239: if (FileUtils.getFileReadOnlyHandler() != null) {
240: FileUtils
241: .getFileReadOnlyHandler()
242: .setFileReadOnly(
243: file,
244: !fileMode
245: .hasPermission(
246: GruntspudFileMode.USER_FILE_MODE_TYPE,
247: GruntspudFileMode.WRITE_PERMISSION));
248: doneWithReadOnlyHandler = true;
249: }
250: // Getting desperate now
251: if (!doneWithReadOnlyHandler) {
252: if (!fileMode.hasPermission(
253: GruntspudFileMode.USER_FILE_MODE_TYPE,
254: GruntspudFileMode.WRITE_PERMISSION))
255: file.setReadOnly();
256: }
257: } catch (IOException ioe) {
258: }
259: }
260: }
261:
262: /**
263: * Return a file mode object given a string
264: *
265: * @param string string representation of the file mode
266: * @return file mode
267: */
268: public static GruntspudFileMode getFileModeForString(
269: String fileModeString) {
270: GruntspudFileMode mode = new GruntspudFileMode();
271: try {
272: StringTokenizer t = new StringTokenizer(fileModeString, ",");
273: while (t.hasMoreTokens()) {
274: String s = t.nextToken();
275: char mnemonic = s.charAt(0);
276: FileModePermission[] permissions = getPermissionsForString(s
277: .substring(2));
278: mode.setPermission(
279: getFileModeTypeForMnemonic(mnemonic),
280: permissions);
281: }
282: } catch (Exception e) {
283: BugLog.getInstance().bug(
284: "Could not parse file mode string '"
285: + fileModeString + "'");
286: BugLog.getInstance().showException(e);
287: }
288: return mode;
289: }
290:
291: /**
292: * Utility to create a <code>FileMode</code> object given a <code>File</code>.
293: * For this to be effective, a <code>FileModeHandler</code> must have been
294: * registered using <code>FileUtil.setFileModeHandler</code>. If no
295: * <code>FileModeHandler</code> is registered, or the registered one
296: * throws an excepion then the FileMode is obtained
297: * using the native <code>File.canRead</code> and <code>File.canWrite</code>
298: * methods. This will <b>NOT</b> take into account 'group' and 'other'
299: * file mode types and 'execute' permission. *
300: *
301: * @param file file to based FileMode on
302: * @return FileMode object
303: */
304: public static GruntspudFileMode getFileModeForFile(File file) {
305: GruntspudFileMode mode = null;
306: int x = 0;
307: if (GruntspudFileUtils.getFileModeHandler() != null) {
308: try {
309: mode = GruntspudFileUtils.getFileModeHandler()
310: .getFileMode(file);
311: } catch (IOException ioe) {
312:
313: BugLog
314: .getInstance()
315: .bug(
316: "**WARNING** Registered FileModeHandler "
317: + "could not determine the file mode for "
318: + file.getAbsolutePath());
319: BugLog.getInstance().showException(ioe);
320: }
321: }
322: if (mode == null) {
323: FileModePermission[] permissions = null;
324: if (file.canRead())
325: if (file.canWrite())
326: permissions = new FileModePermission[] {
327: READ_PERMISSION, WRITE_PERMISSION };
328: else
329: permissions = new FileModePermission[] { READ_PERMISSION };
330: // Unlikely I know, but for neatness ;-)
331: else if (file.canWrite())
332: permissions = new FileModePermission[] { WRITE_PERMISSION };
333: else
334: permissions = new FileModePermission[0];
335: mode = new GruntspudFileMode();
336: mode.setPermission(USER_FILE_MODE_TYPE, permissions);
337: }
338: return mode;
339: }
340:
341: /**
342: * Return how an array of permissions would be represented as a string
343: *
344: * @param fileModePermission array of permissions
345: * @return as a string
346: */
347: public static String permissionsToString(
348: FileModePermission[] permissions) {
349: StringBuffer buf = new StringBuffer();
350: for (int i = 0; i < permissions.length; i++)
351: buf.append(permissions[i].fileModePermissionMnemonic);
352: return buf.toString();
353: }
354:
355: /**
356: * Set the default file mode.
357: *
358: * @param fileMode default file mode
359: */
360: public static void setDefaultFileMode(GruntspudFileMode fileMode) {
361: defaultFileMode = fileMode;
362: }
363:
364: /**
365: * Get the default file mode.
366: *
367: * @return the default file mode
368: */
369: public static GruntspudFileMode getDefaultFileMode() {
370: return defaultFileMode;
371: }
372:
373: // Private instance variables
374:
375: private HashMap permissions;
376:
377: // Statics
378:
379: private static GruntspudFileMode defaultFileMode;
380:
381: static {
382: GruntspudFileMode mode = new GruntspudFileMode(false);
383: mode.setPermission(USER_FILE_MODE_TYPE,
384: new FileModePermission[] { READ_PERMISSION,
385: WRITE_PERMISSION });
386: mode.setPermission(GROUP_FILE_MODE_TYPE,
387: new FileModePermission[] { READ_PERMISSION });
388: mode.setPermission(OTHER_FILE_MODE_TYPE,
389: new FileModePermission[] { READ_PERMISSION });
390: setDefaultFileMode(mode);
391: }
392:
393: static class FileModeType {
394:
395: FileModeType(char fileModeTypeMnemonic) {
396: this .fileModeTypeMnemonic = fileModeTypeMnemonic;
397: }
398:
399: char fileModeTypeMnemonic;
400: }
401:
402: static class FileModePermission {
403:
404: FileModePermission(char fileModePermissionMnemonic) {
405: this .fileModePermissionMnemonic = fileModePermissionMnemonic;
406: }
407:
408: char fileModePermissionMnemonic;
409: }
410: }
|