/*******************************************************************************
* Copyright (c) 2004, 2006
* Thomas Hallgren, Kenneth Olwing, Mitch Sonies
* Pontus Rydin, Nils Unden, Peer Torngren
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the individual
* copyright holders listed above, as Initial Contributors under such license.
* The text of such license is available at www.eclipse.org.
*******************************************************************************/
package org.eclipse.buckminster.p4.preferences;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.buckminster.p4.Messages;
import org.eclipse.buckminster.p4.P4Plugin;
import org.eclipse.buckminster.p4.internal.Connection;
import org.eclipse.buckminster.runtime.BuckminsterException;
import org.eclipse.buckminster.runtime.IOUtils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.util.NLS;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
/**
* @author Thomas Hallgren
*/
public class P4Preferences
{
public static final String ATTR_DEFAULT_SERVER = "defaultServer"; //$NON-NLS-1$
private static final P4Preferences s_instance = new P4Preferences();
/**
* Configure a default server entry based on either the result of executing <code>p4 set</code> or, if that fails,
* the environment variables: <code>P4USER</code>, <code>P4CLIENT</code>, <code>P4PORT</code>, and
* <code>P4PASSWD</code>.
*
* @return The configured server entry.
* @throws BuckminsterException
*/
private static final Pattern rxPattern = Pattern.compile("^(P4[A-Z]+)=(.+?)(?:\\s+\\(set[^\\)]*\\))?+$"); //$NON-NLS-1$
public static P4Preferences getInstance()
{
return s_instance;
}
private final Preferences m_preferences = Platform.getPreferencesService().getRootNode().node(InstanceScope.SCOPE)
.node(P4Plugin.PLUGIN_ID);
public Server addServer(String name) throws BackingStoreException
{
if(m_preferences.nodeExists(name))
throw new BackingStoreException(Messages.name_already_exists);
Server server = new Server(m_preferences.node(name));
if(m_preferences.childrenNames().length == 1)
this.setDefaultServer(name);
return server;
}
public Server configureDefaultServer(Map<String, ? extends Object> scope, boolean overwrite)
throws BackingStoreException, CoreException
{
BufferedReader reader = null;
Map<String, String> p4Properties;
try
{
Process process = Runtime.getRuntime().exec(new String[] { P4Plugin.getDefault().getP4Binary(), "set" }); //$NON-NLS-1$
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
p4Properties = new HashMap<String, String>();
String line;
while((line = reader.readLine()) != null)
{
Matcher m = rxPattern.matcher(line);
if(m.matches())
p4Properties.put(m.group(1), m.group(2));
}
}
catch(IOException e)
{
p4Properties = System.getenv();
}
finally
{
IOUtils.close(reader);
}
String p4Port = p4Properties.get("P4PORT"); //$NON-NLS-1$
if(p4Port == null)
throw BuckminsterException.fromMessage(Messages.missing_environment_P4PORT);
String p4User = p4Properties.get("P4USER"); //$NON-NLS-1$
if(p4User == null)
p4User = System.getProperty("user.name"); //$NON-NLS-1$
String p4Client = p4Properties.get("P4CLIENT"); //$NON-NLS-1$
if(p4Client == null)
throw BuckminsterException.fromMessage(Messages.missing_environment_P4CLIENT);
Server server = this.getServer(p4Port);
if(server == null)
server = this.addServer(p4Port);
else
{
if(!overwrite)
throw BuckminsterException.fromMessage(NLS.bind(Messages.server_0_already_exists, p4Port));
server.clear();
}
server.setUser(p4User);
String p4Passwd = p4Properties.get("P4PASSWD"); //$NON-NLS-1$
if(p4Passwd != null)
server.setPassword(p4Passwd);
server.setAsDefault();
Client client = server.addClient(p4Client);
// Make an attempt to set the default root as stipulated
// by the server if possible.
//
try
{
Connection conn = new Connection(scope, client, p4Port);
conn.getClientSpec();
}
catch(CoreException e)
{
// Will fail when we're off-line. Not a big deal here
}
client.setAsDefault();
this.save();
return server;
}
public Server getDefaultServer() throws BackingStoreException
{
String name = this.getDefaultServerName();
return name == null
? null
: this.getServer(name);
}
public String getDefaultServerName()
{
return m_preferences.get(ATTR_DEFAULT_SERVER, null);
}
public Server getServer(String name) throws BackingStoreException
{
return m_preferences.nodeExists(name)
? new Server(m_preferences.node(name))
: null;
}
public String[] getServerNames() throws BackingStoreException
{
return m_preferences.childrenNames();
}
public Server[] getServers() throws BackingStoreException
{
ArrayList<Server> servers = new ArrayList<Server>();
for(String child : m_preferences.childrenNames())
{
try
{
servers.add(new Server(m_preferences.node(child)));
}
catch(IllegalStateException e)
{
// Someone removed this node during iteration
continue;
}
}
return servers.toArray(new Server[servers.size()]);
}
public void save() throws BackingStoreException
{
m_preferences.flush();
}
public void setDefaultServer(String serverName)
{
if(serverName == null)
m_preferences.remove(ATTR_DEFAULT_SERVER);
else
m_preferences.put(ATTR_DEFAULT_SERVER, serverName);
}
public void setOtherDefaultServer(String serverName) throws BackingStoreException
{
for(String childName : m_preferences.childrenNames())
{
if(!childName.equals(serverName))
{
this.setDefaultServer(childName);
break;
}
}
}
}