001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.mercurial;
043:
044: import java.util.regex.Pattern;
045: import java.util.*;
046: import java.util.prefs.Preferences;
047: import java.io.File;
048: import java.net.InetAddress;
049: import org.netbeans.modules.mercurial.config.HgConfigFiles; //import org.netbeans.modules.mercurial.options.AnnotationExpression;
050: import org.netbeans.modules.mercurial.ui.repository.RepositoryConnection;
051: import org.netbeans.modules.mercurial.util.HgCommand;
052: import org.openide.util.NbPreferences;
053: import org.netbeans.modules.versioning.util.TableSorter;
054: import org.netbeans.modules.versioning.util.Utils;
055:
056: /**
057: * Stores Mercurial module configuration.
058: *
059: * @author Padraig O'Briain
060: */
061: public class HgModuleConfig {
062:
063: public static final String PROP_IGNORED_FILEPATTERNS = "ignoredFilePatterns"; // NOI18N
064: public static final String PROP_COMMIT_EXCLUSIONS = "commitExclusions"; // NOI18N
065: public static final String PROP_DEFAULT_VALUES = "defaultValues"; // NOI18N
066: public static final String PROP_RUN_VERSION = "runVersion"; // NOI18N
067: public static final String KEY_EXECUTABLE_BINARY = "hgExecBinary"; // NOI18N
068: public static final String KEY_EXPORT_FILENAME = "hgExportFilename"; // NOI18N
069: public static final String KEY_EXPORT_FOLDER = "hgExportFolder"; // NOI18N
070: public static final String KEY_IMPORT_FOLDER = "hgImportFolder"; // NOI18N
071: public static final String KEY_ANNOTATION_FORMAT = "annotationFormat"; // NOI18N
072: public static final String SAVE_PASSWORD = "savePassword"; // NOI18N
073: public static final String KEY_BACKUP_ON_REVERTMODS = "backupOnRevert"; // NOI18N
074: public static final String KEY_SHOW_HITORY_MERGES = "showHistoryMerges"; // NOI18N
075:
076: private static final String RECENT_URL = "repository.recentURL"; // NOI18N
077: private static final String SHOW_CLONE_COMPLETED = "cloneCompleted.showCloneCompleted"; // NOI18N
078:
079: private static final String SET_MAIN_PROJECT = "cloneCompleted.setMainProject"; // NOI18N
080:
081: private static final String URL_EXP = "annotator.urlExp"; // NOI18N
082: private static final String ANNOTATION_EXP = "annotator.annotationExp"; // NOI18N
083:
084: public static final String TEXT_ANNOTATIONS_FORMAT_DEFAULT = "{DEFAULT}"; // NOI18N
085:
086: private static final String DEFAULT_EXPORT_FILENAME = "%b_%r_%h"; // NOI18N
087: private static final HgModuleConfig INSTANCE = new HgModuleConfig();
088:
089: private static String userName;
090:
091: public static HgModuleConfig getDefault() {
092: return INSTANCE;
093: }
094:
095: private Set<String> exclusions;
096:
097: // properties ~~~~~~~~~~~~~~~~~~~~~~~~~
098:
099: public Preferences getPreferences() {
100: return NbPreferences.forModule(HgModuleConfig.class);
101: }
102:
103: public boolean getShowCloneCompleted() {
104: return getPreferences().getBoolean(SHOW_CLONE_COMPLETED, true);
105: }
106:
107: public boolean getSetMainProject() {
108: return getPreferences().getBoolean(SET_MAIN_PROJECT, true);
109: }
110:
111: public Pattern[] getIgnoredFilePatterns() {
112: return getDefaultFilePatterns();
113: }
114:
115: public boolean isExcludedFromCommit(String path) {
116: return getCommitExclusions().contains(path);
117: }
118:
119: /**
120: * @param paths collection of paths, of File.getAbsolutePath()
121: */
122: public void addExclusionPaths(Collection<String> paths) {
123: Set<String> exclusions = getCommitExclusions();
124: if (exclusions.addAll(paths)) {
125: Utils.put(getPreferences(), PROP_COMMIT_EXCLUSIONS,
126: new ArrayList<String>(exclusions));
127: }
128: }
129:
130: /**
131: * @param paths collection of paths, File.getAbsolutePath()
132: */
133: public void removeExclusionPaths(Collection<String> paths) {
134: Set<String> exclusions = getCommitExclusions();
135: if (exclusions.removeAll(paths)) {
136: Utils.put(getPreferences(), PROP_COMMIT_EXCLUSIONS,
137: new ArrayList<String>(exclusions));
138: }
139: }
140:
141: public String getExecutableBinaryPath() {
142: return (String) getPreferences().get(KEY_EXECUTABLE_BINARY, ""); // NOI18N
143: }
144:
145: public boolean getBackupOnRevertModifications() {
146: return getPreferences().getBoolean(KEY_BACKUP_ON_REVERTMODS,
147: true);
148: }
149:
150: public void setBackupOnRevertModifications(boolean bBackup) {
151: getPreferences().putBoolean(KEY_BACKUP_ON_REVERTMODS, bBackup);
152: }
153:
154: public boolean getShowHistoryMerges() {
155: return getPreferences()
156: .getBoolean(KEY_SHOW_HITORY_MERGES, true);
157: }
158:
159: public void setShowHistoryMerges(boolean bShowMerges) {
160: getPreferences()
161: .putBoolean(KEY_SHOW_HITORY_MERGES, bShowMerges);
162: }
163:
164: public void setExecutableBinaryPath(String path) {
165: getPreferences().put(KEY_EXECUTABLE_BINARY, path);
166: }
167:
168: public String getExportFolder() {
169: return (String) getPreferences().get(KEY_EXPORT_FOLDER,
170: System.getProperty("user.home")); // NOI18N
171: }
172:
173: public void setExportFolder(String path) {
174: getPreferences().put(KEY_EXPORT_FOLDER, path);
175: }
176:
177: public String getImportFolder() {
178: return (String) getPreferences().get(KEY_IMPORT_FOLDER,
179: System.getProperty("user.home")); // NOI18N
180: }
181:
182: public void setImportFolder(String path) {
183: getPreferences().put(KEY_IMPORT_FOLDER, path);
184: }
185:
186: public String getExportFilename() {
187: String str = (String) getPreferences().get(KEY_EXPORT_FILENAME,
188: ""); // NOI18N
189: if (str.trim().length() == 0)
190: str = DEFAULT_EXPORT_FILENAME;
191: return str;
192: }
193:
194: public void setExportFilename(String path) {
195: getPreferences().put(KEY_EXPORT_FILENAME, path);
196: }
197:
198: /**
199: * This method returns the username specified in $HOME/.hgrc
200: * or /etc/mercurial/hgrc
201: * or a default username if none is found.
202: */
203: public String getUserName() {
204: userName = HgConfigFiles.getInstance().getUserName();
205: if (userName.length() == 0) {
206: String userId = System.getProperty("user.name"); // NOI18N
207: String hostName;
208: try {
209: hostName = InetAddress.getLocalHost().getHostName();
210: } catch (Exception ex) {
211: return userName;
212: }
213: userName = userId + " <" + userId + "@" + hostName + ">"; // NOI18N
214: }
215: return userName;
216: }
217:
218: public void addHgkExtension() {
219: HgConfigFiles.getInstance().setProperty("hgext.hgk", "");
220: }
221:
222: public void setUserName(String name) {
223: HgConfigFiles.getInstance().setUserName(name);
224: }
225:
226: public Boolean isUserNameValid(String name) {
227: if (userName == null)
228: getUserName();
229: if (name.equals(userName))
230: return true;
231: if (name.length() == 0)
232: return true;
233: return HgMail.isUserNameValid(name);
234: }
235:
236: public Boolean isExecPathValid(String name) {
237: if (name.length() == 0)
238: return true;
239: File file = new File(name, HgCommand.HG_COMMAND); // NOI18N
240: // I would like to call canExecute but that requires Java SE 6.
241: if (file.exists() && file.isFile())
242: return true;
243: file = new File(name, HgCommand.HG_COMMAND
244: + HgCommand.HG_WINDOWS_EXE); // NOI18N
245: return file.exists() && file.isFile();
246: }
247:
248: public Properties getProperties(File file) {
249: Properties props = new Properties();
250: HgConfigFiles hgconfig = new HgConfigFiles(file);
251: String name = hgconfig.getUserName(false);
252: if (name.length() == 0)
253: name = getUserName();
254: if (name.length() > 0)
255: props.setProperty("username", name); // NOI18N
256: else
257: props.setProperty("username", ""); // NOI18N
258: name = hgconfig.getDefaultPull(false);
259: if (name.length() > 0)
260: props.setProperty("default-pull", name); // NOI18N
261: else
262: props.setProperty("default-pull", ""); // NOI18N
263: name = hgconfig.getDefaultPush(false);
264: if (name.length() > 0)
265: props.setProperty("default-push", name); // NOI18N
266: else
267: props.setProperty("default-push", ""); // NOI18N
268: return props;
269: }
270:
271: public void clearProperties(File file, String section) {
272: getHgConfigFiles(file).clearProperties(section);
273: }
274:
275: public void removeProperty(File file, String section, String name) {
276: getHgConfigFiles(file).removeProperty(section, name);
277: }
278:
279: public void setProperty(File file, String name, String value) {
280: getHgConfigFiles(file).setProperty(name, value);
281: }
282:
283: public void setProperty(File file, String section, String name,
284: String value, boolean allowEmpty) {
285: getHgConfigFiles(file).setProperty(section, name, value,
286: allowEmpty);
287: }
288:
289: public void setProperty(File file, String section, String name,
290: String value) {
291: getHgConfigFiles(file).setProperty(section, name, value);
292: }
293:
294: /*
295: * Get all properties for a particular section
296: */
297: public Properties getProperties(File file, String section) {
298: return getHgConfigFiles(file).getProperties(section);
299: }
300:
301: private HgConfigFiles getHgConfigFiles(File file) {
302: if (file == null) {
303: return HgConfigFiles.getInstance();
304: } else {
305: return new HgConfigFiles(file);
306: }
307: }
308:
309: public String getAnnotationFormat() {
310: return (String) getPreferences().get(KEY_ANNOTATION_FORMAT,
311: getDefaultAnnotationFormat());
312: }
313:
314: public String getDefaultAnnotationFormat() {
315: return "[{" + MercurialAnnotator.ANNOTATION_STATUS + "} {"
316: + MercurialAnnotator.ANNOTATION_FOLDER + "}]"; // NOI18N
317: }
318:
319: public void setAnnotationFormat(String annotationFormat) {
320: getPreferences().put(KEY_ANNOTATION_FORMAT, annotationFormat);
321: }
322:
323: public boolean getSavePassword() {
324: return getPreferences().getBoolean(SAVE_PASSWORD, true);
325: }
326:
327: public void setSavePassword(boolean bl) {
328: getPreferences().putBoolean(SAVE_PASSWORD, bl);
329: }
330:
331: public void setShowCloneCompleted(boolean bl) {
332: getPreferences().putBoolean(SHOW_CLONE_COMPLETED, bl);
333: }
334:
335: public void setSetMainProject(boolean bl) {
336: getPreferences().putBoolean(SET_MAIN_PROJECT, bl);
337: }
338:
339: public RepositoryConnection getRepositoryConnection(String url) {
340: List<RepositoryConnection> rcs = getRecentUrls();
341: for (Iterator<RepositoryConnection> it = rcs.iterator(); it
342: .hasNext();) {
343: RepositoryConnection rc = it.next();
344: if (url.equals(rc.getUrl())) {
345: return rc;
346: }
347: }
348: return null;
349: }
350:
351: public void insertRecentUrl(RepositoryConnection rc) {
352: Preferences prefs = getPreferences();
353:
354: List<String> urlValues = Utils.getStringList(prefs, RECENT_URL);
355: for (Iterator<String> it = urlValues.iterator(); it.hasNext();) {
356: String rcOldString = it.next();
357: RepositoryConnection rcOld = RepositoryConnection
358: .parse(rcOldString);
359: if (rcOld.equals(rc)) {
360: Utils.removeFromArray(prefs, RECENT_URL, rcOldString);
361: }
362: }
363: Utils.insert(prefs, RECENT_URL, RepositoryConnection
364: .getString(rc), -1);
365: }
366:
367: public void setRecentUrls(List<RepositoryConnection> recentUrls) {
368: List<String> urls = new ArrayList<String>(recentUrls.size());
369:
370: int idx = 0;
371: for (Iterator<RepositoryConnection> it = recentUrls.iterator(); it
372: .hasNext();) {
373: idx++;
374: RepositoryConnection rc = it.next();
375: urls.add(RepositoryConnection.getString(rc));
376: }
377: Preferences prefs = getPreferences();
378: Utils.put(prefs, RECENT_URL, urls);
379: }
380:
381: public List<RepositoryConnection> getRecentUrls() {
382: Preferences prefs = getPreferences();
383: List<String> urls = Utils.getStringList(prefs, RECENT_URL);
384: List<RepositoryConnection> ret = new ArrayList<RepositoryConnection>(
385: urls.size());
386: for (Iterator<String> it = urls.iterator(); it.hasNext();) {
387: RepositoryConnection rc = RepositoryConnection.parse(it
388: .next());
389: ret.add(rc);
390: }
391: return ret;
392: }
393:
394: //public void setAnnotationExpresions(List<AnnotationExpression> exps) {
395: // List<String> urlExp = new ArrayList<String>(exps.size());
396: // List<String> annotationExp = new ArrayList<String>(exps.size());
397:
398: // int idx = 0;
399: // for (Iterator<AnnotationExpression> it = exps.iterator(); it.hasNext();) {
400: // idx++;
401: // AnnotationExpression exp = it.next();
402: // urlExp.add(exp.getUrlExp());
403: // annotationExp.add(exp.getAnnotationExp());
404: // }
405:
406: // Preferences prefs = getPreferences();
407: // Utils.put(prefs, URL_EXP, urlExp);
408: // Utils.put(prefs, ANNOTATION_EXP, annotationExp);
409: //}
410:
411: //public List<AnnotationExpression> getAnnotationExpresions() {
412: // Preferences prefs = getPreferences();
413: // List<String> urlExp = Utils.getStringList(prefs, URL_EXP);
414: // List<String> annotationExp = Utils.getStringList(prefs, ANNOTATION_EXP);
415:
416: // List<AnnotationExpression> ret = new ArrayList<AnnotationExpression>(urlExp.size());
417: // for (int i = 0; i < urlExp.size(); i++) {
418: // ret.add(new AnnotationExpression(urlExp.get(i), annotationExp.get(i)));
419: // }
420: // if(ret.size() < 1) {
421: // ret = getDefaultAnnotationExpresions();
422: // }
423: // return ret;
424: //}
425:
426: //public List<AnnotationExpression> getDefaultAnnotationExpresions() {
427: // List<AnnotationExpression> ret = new ArrayList<AnnotationExpression>(1);
428: // ret.add(new AnnotationExpression(".*/(branches|tags)/(.+?)/.*", "\\2")); // NOI18N
429: // return ret;
430: //}
431:
432: // TODO: persist state
433:
434: private TableSorter importTableSorter;
435: private TableSorter commitTableSorter;
436:
437: public TableSorter getImportTableSorter() {
438: return importTableSorter;
439: }
440:
441: public void setImportTableSorter(TableSorter sorter) {
442: importTableSorter = sorter;
443: }
444:
445: public TableSorter getCommitTableSorter() {
446: return commitTableSorter;
447: }
448:
449: public void setCommitTableSorter(TableSorter sorter) {
450: commitTableSorter = sorter;
451: }
452:
453: // private methods ~~~~~~~~~~~~~~~~~~
454:
455: private synchronized Set<String> getCommitExclusions() {
456: if (exclusions == null) {
457: exclusions = new HashSet<String>(Utils.getStringList(
458: getPreferences(), PROP_COMMIT_EXCLUSIONS));
459: }
460: return exclusions;
461: }
462:
463: private static Pattern[] getDefaultFilePatterns() {
464: return new Pattern[] { Pattern.compile("cvslog\\..*"), // NOI18N
465: Pattern.compile("\\.make\\.state"), // NOI18N
466: Pattern.compile("\\.nse_depinfo"), // NOI18N
467: Pattern.compile(".*~"), // NOI18N
468: Pattern.compile("#.*"), // NOI18N
469: Pattern.compile("\\.#.*"), // NOI18N
470: Pattern.compile(",.*"), // NOI18N
471: Pattern.compile("_\\$.*"), // NOI18N
472: Pattern.compile(".*\\$"), // NOI18N
473: Pattern.compile(".*\\.old"), // NOI18N
474: Pattern.compile(".*\\.bak"), // NOI18N
475: Pattern.compile(".*\\.BAK"), // NOI18N
476: Pattern.compile(".*\\.orig"), // NOI18N
477: Pattern.compile(".*\\.rej"), // NOI18N
478: Pattern.compile(".*\\.del-.*"), // NOI18N
479: Pattern.compile(".*\\.a"), // NOI18N
480: Pattern.compile(".*\\.olb"), // NOI18N
481: Pattern.compile(".*\\.o"), // NOI18N
482: Pattern.compile(".*\\.obj"), // NOI18N
483: Pattern.compile(".*\\.so"), // NOI18N
484: Pattern.compile(".*\\.exe"), // NOI18N
485: Pattern.compile(".*\\.Z"), // NOI18N
486: Pattern.compile(".*\\.elc"), // NOI18N
487: Pattern.compile(".*\\.ln"), // NOI18N
488: };
489: }
490: }
|