tikhomirov@378: /* tikhomirov@378: * Copyright (c) 2012 TMate Software Ltd tikhomirov@378: * tikhomirov@378: * This program is free software; you can redistribute it and/or modify tikhomirov@378: * it under the terms of the GNU General Public License as published by tikhomirov@378: * the Free Software Foundation; version 2 of the License. tikhomirov@378: * tikhomirov@378: * This program is distributed in the hope that it will be useful, tikhomirov@378: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@378: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@378: * GNU General Public License for more details. tikhomirov@378: * tikhomirov@378: * For information on how to redistribute this software under tikhomirov@378: * the terms of a license other than GNU General Public License tikhomirov@378: * contact TMate Software at support@hg4j.com tikhomirov@378: */ tikhomirov@378: package org.tmatesoft.hg.core; tikhomirov@378: tikhomirov@378: import java.io.File; tikhomirov@378: import java.io.IOException; tikhomirov@378: import java.util.ArrayList; tikhomirov@378: import java.util.LinkedHashMap; tikhomirov@378: import java.util.List; tikhomirov@378: import java.util.Map; tikhomirov@378: tikhomirov@378: import org.tmatesoft.hg.internal.ConfigFile; tikhomirov@378: import org.tmatesoft.hg.internal.Experimental; tikhomirov@378: import org.tmatesoft.hg.internal.Internals; tikhomirov@382: import org.tmatesoft.hg.repo.HgInternals; tikhomirov@378: import org.tmatesoft.hg.repo.HgRepository; tikhomirov@378: tikhomirov@378: /** tikhomirov@378: * WORK IN PROGRESS, DO NOT USE tikhomirov@378: * tikhomirov@378: * @author Artem Tikhomirov tikhomirov@378: * @author TMate Software Ltd. tikhomirov@378: */ tikhomirov@378: @Experimental(reason="Investigating approaches to alter Hg configuration files") tikhomirov@378: public final class HgUpdateConfigCommand extends HgAbstractCommand { tikhomirov@378: tikhomirov@378: private final File configFile; tikhomirov@378: tikhomirov@378: private Map> toRemove; tikhomirov@378: private Map> toSet; tikhomirov@378: tikhomirov@483: private final SessionContext sessionCtx; tikhomirov@483: tikhomirov@483: private HgUpdateConfigCommand(SessionContext sessionContext, File configurationFile) { tikhomirov@483: sessionCtx = sessionContext; tikhomirov@378: configFile = configurationFile; tikhomirov@378: } tikhomirov@378: tikhomirov@378: public static HgUpdateConfigCommand forRepository(HgRepository hgRepo) { tikhomirov@490: // XXX HgRepository to implement SessionContext.Provider (with getContext())? tikhomirov@490: return new HgUpdateConfigCommand(hgRepo.getSessionContext(), new File(HgInternals.getRepositoryDir(hgRepo), "hgrc")); tikhomirov@378: } tikhomirov@378: tikhomirov@382: public static HgUpdateConfigCommand forUser(SessionContext ctx) { tikhomirov@483: return new HgUpdateConfigCommand(ctx, Internals.getUserConfigurationFileToWrite(ctx)); tikhomirov@378: } tikhomirov@378: tikhomirov@382: public static HgUpdateConfigCommand forInstallation(SessionContext ctx) { tikhomirov@483: return new HgUpdateConfigCommand(ctx, Internals.getInstallationConfigurationFileToWrite(ctx)); tikhomirov@378: } tikhomirov@378: tikhomirov@378: /** tikhomirov@378: * Remove a property altogether tikhomirov@378: * @return this for convenience tikhomirov@378: */ tikhomirov@378: public HgUpdateConfigCommand remove(String section, String key) { tikhomirov@378: if (toRemove == null) { tikhomirov@378: toRemove = new LinkedHashMap>(); tikhomirov@378: } tikhomirov@378: List s = toRemove.get(section); tikhomirov@378: if (s == null) { tikhomirov@378: toRemove.put(section, s = new ArrayList(5)); tikhomirov@378: } tikhomirov@378: s.add(key); tikhomirov@378: if (toSet != null && toSet.containsKey(section)) { tikhomirov@378: toSet.get(section).remove(key); tikhomirov@378: } tikhomirov@378: return this; tikhomirov@378: } tikhomirov@378: tikhomirov@378: /** tikhomirov@378: * Delete single attribute in a multi-valued property tikhomirov@378: * @return this for convenience tikhomirov@378: */ tikhomirov@378: public HgUpdateConfigCommand remove(String section, String key, String value) { tikhomirov@378: throw new UnsupportedOperationException(); tikhomirov@378: } tikhomirov@378: tikhomirov@378: /** tikhomirov@378: * Set single-valued properties or update multi-valued with a single value tikhomirov@378: * @return this for convenience tikhomirov@378: */ tikhomirov@378: public HgUpdateConfigCommand put(String section, String key, String value) { tikhomirov@378: if (toSet == null) { tikhomirov@378: toSet = new LinkedHashMap>(); tikhomirov@378: } tikhomirov@378: Map s = toSet.get(section); tikhomirov@378: if (s == null) { tikhomirov@378: toSet.put(section, s = new LinkedHashMap()); tikhomirov@378: } tikhomirov@378: s.put(key, value); tikhomirov@378: return this; tikhomirov@378: } tikhomirov@378: tikhomirov@378: /** tikhomirov@378: * Multi-valued properties tikhomirov@378: * @return this for convenience tikhomirov@378: */ tikhomirov@378: public HgUpdateConfigCommand add(String section, String key, String value) { tikhomirov@378: throw new UnsupportedOperationException(); tikhomirov@378: } tikhomirov@378: tikhomirov@427: /** tikhomirov@427: * Perform config file update tikhomirov@427: * tikhomirov@427: * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state tikhomirov@427: */ tikhomirov@378: public void execute() throws HgException { tikhomirov@378: try { tikhomirov@483: ConfigFile cfg = new ConfigFile(sessionCtx); tikhomirov@378: cfg.addLocation(configFile); tikhomirov@378: if (toRemove != null) { tikhomirov@378: for (Map.Entry> s : toRemove.entrySet()) { tikhomirov@378: for (String e : s.getValue()) { tikhomirov@378: cfg.putString(s.getKey(), e, null); tikhomirov@378: } tikhomirov@378: } tikhomirov@378: } tikhomirov@378: if (toSet != null) { tikhomirov@378: for (Map.Entry> s : toSet.entrySet()) { tikhomirov@378: for (Map.Entry e : s.getValue().entrySet()) { tikhomirov@378: cfg.putString(s.getKey(), e.getKey(), e.getValue()); tikhomirov@378: } tikhomirov@378: } tikhomirov@378: } tikhomirov@378: cfg.writeTo(configFile); tikhomirov@378: } catch (IOException ex) { tikhomirov@427: String m = String.format("Failed to update configuration file %s", configFile); tikhomirov@427: throw new HgBadArgumentException(m, ex); // TODO [post-1.0] better exception, it's not bad argument case tikhomirov@378: } tikhomirov@378: } tikhomirov@378: tikhomirov@378: tikhomirov@378: public static void main(String[] args) throws Exception { tikhomirov@378: HgUpdateConfigCommand cmd = HgUpdateConfigCommand.forUser(null); tikhomirov@378: cmd.remove("test1", "sample1"); tikhomirov@378: cmd.put("test2", "sample2", "value2"); tikhomirov@378: cmd.put("ui", "user-name", "Another User "); tikhomirov@378: cmd.execute(); tikhomirov@378: } tikhomirov@378: }