/******************************* Copyright notice ******************************* Copyright (C)2002 by Andrei Loskutov <loskutov@gmx.de>. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ********************************************************************************/ /** * Created on 29.11.2002 * * To change this generated comment edit the template variable "filecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of file comments go to * Window>Preferences>Java>Code Generation. */ package adiag.connection; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Observable; import java.util.Observer; import javax.swing.JFrame; import javax.swing.JOptionPane; import adiag.model.Const; /** * @author Andy the Great * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ public class Configuration extends Observable implements Observer { /** the path to config (branchview.ini) file */ private static String iniUrl; private String path; /** is offline modus ? */ private boolean offline; private JFrame app; /** is debug on? */ private boolean debug; /** current connector */ private Connector conn; /** administrator of settings and config - file */ protected static PropertySetter propsSetter; /** path to external diff tool */ private String diffPath = Const.DIFF_FILE; /** is props on ? */ private boolean propsEnable; public Configuration(){ if(propsSetter == null){ propsSetter = new PropertySetter(); } propsSetter.addObserver(this); } /** * See return description * @return current path to diff tool */ public String getDiffPath() { return diffPath; } /** * See return description * @return boolean true, if we are in offline mode (no direct connection to p4 process) */ public boolean isOffline() { return this.offline; } /** * Set new path to diff tool * @param newpath path to diff tool */ public void setDiffPath(String newpath) { this.diffPath = newpath; } /** * Set flag to discover all known branches at one time * @param on true for all, false only for selected */ public void setDiscoverAllBranches(boolean on){ this.discover_all = on; } /** should we fetch all branches by start ? * (try to discover all known branches) */ private boolean discover_all = true; /** * See return description * @return boolean true, if we must write log file */ public boolean isDebug() { return this.debug; } /** * See return description * @return boolean true to discover all known branches at one time, * false only for selected branch */ public boolean isDiscoverAllBranches(){ return this.discover_all; } public String getPath(){ return path; } public JFrame getJComponent(){ return app; } public void setJComponent(JFrame app){ this.app = app; } /** * See return description * @param key option name, one of Const.PROPERTY_ - constants * @return String current value for given props key, or empty string */ public String getProperty(String key){ String value = propsSetter.getProps(this).getProperty(key, getDefaultProperty(key)); if(Const.PROPERTY_P4_PASSWD.equals(key)){ if(value!=null && value.length()!=0 ){ // decode passwort try { value = new String (toByteBlock(value)); } catch (Exception e) { e.printStackTrace(); } } } return value; } /** * See return description * @param key option name, one of Const.PROPERTY_ - constants * @return String default value for given props key, or empty string */ public String getDefaultProperty(String key){ if(Const.PROPERTY_DEBUG.equals(key)){ return "true"; } else if(Const.PROPERTY_OFFLINE.equals(key)){ return "false"; } else if(Const.PROPERTY_DISCOVER_ALL.equals(key)){ return "true"; } else if(Const.PROPERTY_DIFF_FILE.equals(key)){ return Const.DIFF_FILE; } else if(Const.PROPERTY_P4_CLIENT.equals(key)){ return ""; } else if(Const.PROPERTY_P4_EXEC.equals(key)){ return Const.P4_EXE_FILE; } else if(Const.PROPERTY_P4_PASSWD.equals(key)){ return ""; } else if(Const.PROPERTY_P4_PORT.equals(key)){ return "1666"; } else if(Const.PROPERTY_P4_USER.equals(key)){ return ""; } return ""; } /** * Prepare environement. This is not really clear and conventional, but fast ;) * @param param die Parameter: see online help :) * @throws Exception if something goes wrong */ public String parseParameter(String[] param) throws Exception { String start_error = null; // clean all shit if(getConnector()!= null){ setConnector(null); } // read and set all to default, if not found if(!propsSetter.isInitDone()){ propsSetter.readProps(this); } setDiffPath(getProperty(Const.PROPERTY_DIFF_FILE)); // prepare environement: on Windows-systems is all in registry if(Const.indexOfString(param, "-stat") >= 0){ propsSetter.setProperty(Const.PROPERTY_DEBUG, "true", this); } else { setDebug(getProperty(Const.PROPERTY_DEBUG).equalsIgnoreCase("true")); } if(Const.indexOfString(param, "-offline") >= 0){ propsSetter.setProperty(Const.PROPERTY_OFFLINE, "true", this); } else { setOffline(getProperty(Const.PROPERTY_OFFLINE).equalsIgnoreCase("true")); } if(Const.indexOfString(param, "-all") >= 0){ propsSetter.setProperty(Const.PROPERTY_DISCOVER_ALL, "true", this); } else { setDiscoverAllBranches(getProperty(Const.PROPERTY_DISCOVER_ALL).equalsIgnoreCase("true")); } // cleanup param = remove(param, "-props"); param = remove(param, "-stat"); param = remove(param, "-offline"); param = remove(param, "-all"); if (param.length == 1 ) { setPath(param[0]); } else if (param.length > 3) { propsSetter.setProperty(Const.PROPERTY_P4_USER, param[0], this); propsSetter.setProperty(Const.PROPERTY_P4_CLIENT, param[1], this); propsSetter.setProperty(Const.PROPERTY_P4_PORT, param[2], this); setPath(param[3]); if(param.length > 4){ propsSetter.setProperty(Const.PROPERTY_P4_EXEC, param[4], this); if(param.length > 5 ){ propsSetter.setProperty(Const.PROPERTY_P4_PASSWD, param[5], this); } } } // no path received? go offline if (param.length == 0 && !isOffline()){ this.setOffline(true); } if("".equals(getProperty(Const.PROPERTY_P4_USER)) || "".equals(getProperty(Const.PROPERTY_P4_CLIENT)) || "".equals(getProperty(Const.PROPERTY_P4_PORT))){ propsSetter.setProperty(Const.PROPERTY_OFFLINE, "true", this); start_error = "P4 user, port or client is not set.\n\nCurrent configuration is:\n" + "user: '" + getProperty(Const.PROPERTY_P4_USER) + "'\n" + "client: '" + getProperty(Const.PROPERTY_P4_CLIENT) + "'\n" + "port: '" + getProperty(Const.PROPERTY_P4_PORT) + "'\n" + "--------------\nDon't worry, press F1 for help or '<Ctrl> + <P>' for properties!"; } propsSetter.storeProperties(this); return start_error; } /** See return description * @param sa array * @param s String to remove from array * @return new array without given string */ public static String[] remove(String[] sa, String s) { ArrayList al = new ArrayList(Arrays.asList(sa)); String st = null; for (int i = al.size() - 1; i >= 0; i--) { st = al.get(i).toString(); if (st.equals(s)) { al.remove(i); } } return (String[]) al.toArray(new String[al.size()]); } /** * Show error dialog * @param message error description for user * @param error error instance or null */ public void error(String message, Throwable error) { if(!app.isVisible()){ System.out.println(message); } else { JOptionPane.showMessageDialog(app, message, "Error!", JOptionPane.ERROR_MESSAGE); } if(error != null){ error.printStackTrace(); } } /** * see return description * @return String path to config file */ protected static String getIniUrl(){ if(iniUrl == null){ iniUrl = System.getProperty("user.home") + System.getProperty("file.separator") + Const.INI_FILE; } return iniUrl; } /** * see return description * @return PropertySetter administrator of settings and config - file */ public PropertySetter getPropsSetter(){ if(propsSetter == null){ propsSetter = new PropertySetter(); } return propsSetter; } /** * Set flag to write log file * @param on true, if we must write log file */ public void setDebug(boolean on) { this.debug = on; } /** * Set current path to retrieve data from P4 * @param newpath the current path to P4 file */ public void setPath(String newpath) { this.path = newpath; setChanged(); this.notifyObservers(getPath()); } /** * Set current connector * @param newConn new connector */ public void setConnector(Connector newConn) { Connector c = getConnector(); // close connector and write log if available if(c != null) { try { if (isDebug() && !isOffline()) { write(c.dataToString(), c.getLogFile()); } if(newConn == null){ // clear all c.dispose(); } else { c.close(); } } catch (Exception ee) { error("Cannot write log file:\n" + ee.getMessage(), ee); } } this.conn = newConn; } /** * see return description * @return Currently used connector or null */ public Connector getConnector() { return conn; } /** Write string to file * @param s content to write * @param file file to write to * @throws Exception, if file not exist,cannot be open, is directory etc. */ public static void write(String s, File file) throws Exception { if (file == null) throw new Exception("Given file is null."); if (file.isDirectory()) throw new Exception( "Given file is directory, cannot write in:" + file.getPath()); if (file.exists() && !file.canWrite()) throw new Exception("Given file don't exist or you have not right to write in:" + file.getPath()); PrintWriter out; try { out = new PrintWriter(new BufferedWriter(new FileWriter(file)), false); } catch (IOException e) { e.printStackTrace(); throw new Exception("I/O error during write into file:" + file.getPath()); } out.print(s); out.flush(); out.close(); } /** * Set on/offline mode * @param on true to receive data from "old" log file or "offline" */ public void setOffline(boolean on) { Connector c = getConnector(); if(isOffline() == on && c != null){ return; } this.offline = on; if (isOffline()) { c = new FileLogConnector(this); //System.out.println("working offline..."); } else { c = new P4CommandConnector(this); //System.out.println("working online..."); } setConnector(c); } /** * Show custom panel + buttons "ok" and "cancel" as modal dialog * @param panel custom panel to edit by user * @param title dialog title * @return given panel (data may be changed by user), or null if user has "cancel" dialog */ public Object object(Object panel, String title) { Object[] options = { "Ok", "Cancel" }; int i = JOptionPane.showOptionDialog( app, panel, title, JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]); if (i == JOptionPane.YES_OPTION) { return panel; } else { return null; } } /* (non-Javadoc) * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable o, Object arg) { String changed_property = propsSetter.getLastChangedProperty(); if(changed_property == null){ return; } String value = "" + arg; if(Const.PROPERTY_DEBUG.equals(changed_property)){ setDebug(Boolean.valueOf(value).booleanValue()); } if(Const.PROPERTY_OFFLINE.equals(changed_property)){ setOffline(Boolean.valueOf(value).booleanValue()); } else if(Const.PROPERTY_DISCOVER_ALL.equals(changed_property)){ setDiscoverAllBranches(Boolean.valueOf(value).booleanValue()); } else if(Const.PROPERTY_DIFF_FILE.equals(changed_property)){ setDiffPath(value); } } /** Convert a block to a String representation. * @param block bytearray to convert to String. * @param off convert from * @param len convert length * @return String representations of given bytearray. Each byte will be splitten into 2 halfbytes * and each halfbyte will be converted to one of these caracters: * 0123456789abcdef. * Returned String has always even length. */ public static String toStringBlock(byte[] block, int off, int len) { String hexits = "0123456789abcdef"; StringBuffer buf = new StringBuffer(); for (int i = off; i < off + len; ++i) { buf.append(hexits.charAt((block[i] >>> 4) & 0xf)); // get high byte buf.append(hexits.charAt(block[i] & 0xf)); // get low byte } return buf.toString(); } /** Convert a block to a String representation. * @param block bytearray to convert to String. * @return String representations of given bytearray. Each byte will be splitten into 2 halfbytes * and each halfbyte will be converted to one of these caracters: * 0123456789abcdef. * Returned String has always even length. */ public static String toStringBlock(byte[] block) { return toStringBlock(block, 0, block.length); } /** Convert a String block to a byte block representation. * @return byte representation of given String, or null if string not rigth decoded from byte[] * @param block String block. Can contain only these caracters: 0123456789abcdef. * @param len decode length, must be even * @param off decode from * @throws ExplainedException if characters are wrong(not "0123456789abcdef") * or number of then is not even */ public static byte[] toByteBlock(String block, int off, int len) throws Exception { String hexits = "0123456789abcdef"; char[] chars = block.toCharArray(); // has requested block even length? if (len % 2 != 0) { // 0 or 1, must be always 0 !!! throw new Exception("Error! Valid string block must have even number of characters!"); } // has this block only allowed characters? for (int i = 0; i < chars.length; i++) { if (hexits.indexOf(chars[i]) < 0) { throw new Exception( "Error! Valid string block must have only these 16 characters: '" + hexits + "'!"); } } // all right now, also decoding int length = (int) len / 2; byte[] bytes = new byte[length]; int j = 0; int hibyte, lowbyte; for (int i = off; i < off + len; ++i) { hibyte = hexits.indexOf(chars[i]); lowbyte = hexits.indexOf(chars[++i]); bytes[j++] = (byte) ((hibyte << 4) | lowbyte); } return bytes; } /** Convert a String block to a byte block representation. * @param block String block. Can contain only these caracters: * 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f. * @return bytearray whith string representation, if all right. * @throws Exception, if block is null */ public static byte[] toByteBlock(String block) throws Exception { if (block == null || block.length() < 0) { throw new Exception("Error! Empty string block! "); } //if (block.charAt(0) != '[' // || block.charAt(block.length() - 1) != ']') { // throw new Exception("Error! Missed '[' or ']'!"); //} //block = block.substring(1, block.length() - 1); //cut leaded "[" and end "]" return toByteBlock(block, 0, block.length()); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#4 | 2735 | andrei_loskutov | sources are now included to binary distribution at http://andrei.gmxhome.de/perforce/index.html | ||
#3 | 2554 | andrei_loskutov |
#25.12.2002 23:29 Revision 1.3.0.4 beta 1) Some small refactoring 2) First integration with P4eclipse: properties etc, thanks Boris Pr�ssmann 5) Better integration to Eclipse: use Eclipse internal compare tool for diff. 6) Fix some minor bugs. #14.12.2002 23:15 Revision 1.3.0.3 beta 1) Fix endless loop bug if p4 path was not set. 2) Fix never getting focus bug after error message shown 3) Fix painting bug on JDK 1.4.1 (must be verified!!!) 4) Some small refactoring 5) Fix error handling. 6) Fix some minor bugs. |
||
#2 | 2552 | andrei_loskutov | 1.3.0.4 changes | ||
#1 | 2460 | andrei_loskutov |
1) Change configuration: always reed properties 2) Change password store to hex format/password field 3) Create standalone/not standalone state for new branchview eclipse wrapper 4) Refactor all main classes to remove cyclic package dependency 5) Add workaround to fix new JDK 1.4.1 Swing bugs on JScrollPane/JViewPort 6) Add dispose methods to panel/connector 7) Minor internal GUI fixes/refactorings |