commit 1c78c0462c6d49935f91da0bd399e80ac7058b05 Author: Christian P. MOMON Date: Thu Jun 17 21:34:38 2010 +0200 First commit. diff --git a/lib/commons-codec-1.4.jar b/lib/commons-codec-1.4.jar new file mode 100644 index 0000000..458d432 Binary files /dev/null and b/lib/commons-codec-1.4.jar differ diff --git a/lib/commons-fileupload-1.2.1.jar b/lib/commons-fileupload-1.2.1.jar new file mode 100644 index 0000000..aa209b3 Binary files /dev/null and b/lib/commons-fileupload-1.2.1.jar differ diff --git a/lib/commons-io-1.4.jar b/lib/commons-io-1.4.jar new file mode 100644 index 0000000..133dc6c Binary files /dev/null and b/lib/commons-io-1.4.jar differ diff --git a/lib/log4j-1.2.14.jar b/lib/log4j-1.2.14.jar new file mode 100644 index 0000000..6251307 Binary files /dev/null and b/lib/log4j-1.2.14.jar differ diff --git a/src/CmdExecTester.java b/src/CmdExecTester.java new file mode 100644 index 0000000..c32a911 --- /dev/null +++ b/src/CmdExecTester.java @@ -0,0 +1,126 @@ +/** + * XidvcTest. + */ + +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import fr.devinsy.util.cmdexec.CmdExec; +import fr.devinsy.util.cmdexec.StreamGobbler; +import fr.devinsy.util.unix.Unix; +import fr.devinsy.xidvc.*; + + +/** + * + */ +class CmdExecTester +{ + static private org.apache.log4j.Logger logger; + + static + { + // Initialize logger. + org.apache.log4j.Logger logger = null; + + org.apache.log4j.BasicConfigurator.configure (); + + + logger = org.apache.log4j.Logger.getRootLogger (); + //logger.setLevel (org.apache.log4j.Level.INFO); + logger.setLevel (org.apache.log4j.Level.INFO); + + logger.info ("Enter"); + + // + logger.info ("Set the log file format..."); + + + // log = org.apache.log4j.Category.getInstance(Application.class.getName()); + logger.info ("... done."); + + logger.debug ("Exit"); + logger = org.apache.log4j.Logger.getLogger (CmdExecTester.class); + } + + + + /** + * + */ + public static String check (String title, StringBuffer source, String model) + { + String result; + + if (source.indexOf (model) == -1) + { + result = String.format ("%-40s -> KO <-", title) + "\nGet:\n" + source + "\nWaiting:\n" + model; + + } + else + { + result = String.format ("%-40s [ OK ] ", title); + } + + + // + return (result); + } + + + /** + * + */ + public static String testCaller (String pathInfo, String prefix) + { + String result; + + result = "[" + pathInfo + "]=>[" + ServletDispatcher.pathInfoToClassName(pathInfo, prefix) + "]"; + + // + return(result); + } + + + /** + * + */ + public static void test1() + { + try + { + System.out.println("Launch ..."); + + //String command = "/bin/sort -r /etc/passwd"; + String[] command = {"/bin/sort", "-r", "/etc/passwd"}; + + CmdExec cmd = new CmdExec (command, StreamGobbler.BUFFER, StreamGobbler.BUFFER); + System.out.println("exitVal=[" + cmd.getExitValue() + "]"); + System.out.println("out=[" + cmd.getOutStream() + "]"); + System.out.println("err=[" + cmd.getErrStream() + "]"); + } + catch (Exception exception) + { + exception.printStackTrace(); + logger.info("ERRRO=" + exception); + } + } + + /** + * + */ + public static void main(String[] args) + { + System.out.println("Automatic test action for CmdExec!"); + + Matcher m = Pattern.compile("^#\\sowner:\\s([a-z_][a-z0-9_-]*)$").matcher("# owner: cpm"); + m.matches(); + //System.out.println("owner=[" + m.matches() + "]"); + System.out.println("owner=[" + m.groupCount() + "]"); + System.out.println("owner=[" + m.group(1) + "]"); + //test1(); + + + } +} diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..5e94951 --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/src/XidvcTester.java b/src/XidvcTester.java new file mode 100644 index 0000000..fb51ac9 --- /dev/null +++ b/src/XidvcTester.java @@ -0,0 +1,94 @@ +/** + * XidvcTest. + */ + +import java.io.File; +import java.util.regex.Pattern; + +import fr.devinsy.util.unix.Unix; +import fr.devinsy.xidvc.*; + + +/** + * + */ +class XidvcTester +{ + static private org.apache.log4j.Logger logger; + + static + { + // Initialize logger. + org.apache.log4j.Logger logger = null; + + org.apache.log4j.BasicConfigurator.configure (); + + + logger = org.apache.log4j.Logger.getRootLogger (); + //logger.setLevel (org.apache.log4j.Level.INFO); + logger.setLevel (org.apache.log4j.Level.INFO); + + logger.info ("Enter"); + + // + logger.info ("Set the log file format..."); + + + // log = org.apache.log4j.Category.getInstance(Application.class.getName()); + logger.info ("... done."); + + logger.debug ("Exit"); + logger = org.apache.log4j.Logger.getLogger (XidvcTester.class.getName ()); + } + + + + /** + * + */ + public static String check (String title, StringBuffer source, String model) + { + String result; + + if (source.indexOf (model) == -1) + { + result = String.format ("%-40s -> KO <-", title) + "\nGet:\n" + source + "\nWaiting:\n" + model; + + } + else + { + result = String.format ("%-40s [ OK ] ", title); + } + + + // + return (result); + } + + + /** + * + */ + public static String testCaller (String pathInfo, String prefix) + { + String result; + + result = "[" + pathInfo + "]=>[" + ServletDispatcher.pathInfoToClassName(pathInfo, prefix) + "]"; + + // + return(result); + } + + /** + * + */ + public static void main(String[] args) + { + System.out.println ("----------------------------"); + System.out.println(testCaller("/", "fr.devinsy.website")); + System.out.println(testCaller("/good/", "fr.devinsy.website")); + System.out.println(testCaller("/good/morning", "fr.devinsy.website")); + System.out.println(testCaller("/good/day_day", "fr.devinsy.website")); + System.out.println(testCaller("/good/day.xhtml", "fr.devinsy.website")); + } +} diff --git a/src/fr/devinsy/util/DataFile.java b/src/fr/devinsy/util/DataFile.java new file mode 100644 index 0000000..7737cb9 --- /dev/null +++ b/src/fr/devinsy/util/DataFile.java @@ -0,0 +1,244 @@ +/** + * @author Christian Momon, June 2008. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + + +/** + * This class defines a content file. + * + */ +public class DataFile +{ + static public int NOID = 0; + static public int DEFAULT_SIZE = 0; + + // + protected int id; + protected int contentId; + protected String name; + protected long size; + protected byte[] data; + protected String creationDate; + protected String creationUser; + + /** + * + */ + public DataFile () + { + this.id = NOID; + this.contentId = NOID; + this.name = null; + this.size = DEFAULT_SIZE; + this.data = null; + this.creationDate = null; + this.creationUser = null; + } + + /** + * + */ + public DataFile (String name, long size, byte[] data) + { + this.id = NOID; + this.contentId = NOID; + this.name = name; + this.size = size; + this.data = data; + this.creationDate = null; + this.creationUser = null; + } + + /** + * + */ + public DataFile (int contentId, String name, long size, byte[] data) + { + this.id = NOID; + this.contentId = contentId; + this.name = name; + this.size = size; + this.data = data; + this.creationDate = null; + this.creationUser = null; + } + + /** + * + */ + public int id () + { + int result; + + result = this.id; + + // + return (result); + } + + + /** + * + */ + public void setId (int id) + { + this.id = id; + } + + /** + * + */ + public int contentId () + { + int result; + + result = this.contentId; + + // + return (result); + } + + /** + * + */ + public void setContentId (int contentId) + { + this.contentId = contentId; + } + + /** + * + */ + public String name () + { + String result; + + result = this.name; + + // + return (result); + } + + /** + * + */ + public void setName (String name) + { + if (name == null) + { + this.name = ""; + } + else + { + this.name = name; + } + } + + /** + * + */ + public long size () + { + long result; + + result = this.size; + + // + return (result); + } + + /** + * + */ + public void setSize (long size) + { + if (size >= 0) + { + this.size = size; + } + else + { + this.size = 0; + } + } + + /** + * + */ + public byte[] data () + { + byte[] result; + + result = this.data; + + // + return (result); + } + + /** + * + */ + public void setData (byte[] data) + { + this.data = data; + } + + /** + * + */ + public String creationDate () + { + String result; + + result = this.creationDate; + + // + return (result); + } + + /** + * + */ + public void setCreationDate (String creationDate) + { + if (creationDate == null) + { + this.creationDate = ""; + } + else + { + this.creationDate = creationDate; + } + } + + /** + * + */ + public String creationUser () + { + String result; + + result = this.creationUser; + + // + return (result); + } + + /** + * + */ + public void setCreationUser (String creationUser) + { + if (creationUser == null) + { + this.creationUser = ""; + } + else + { + this.creationUser = creationUser; + } + } +} diff --git a/src/fr/devinsy/util/DataFiles.java b/src/fr/devinsy/util/DataFiles.java new file mode 100644 index 0000000..12dcae9 --- /dev/null +++ b/src/fr/devinsy/util/DataFiles.java @@ -0,0 +1,172 @@ +/** + * @author Christian Momon, June 2008. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + +import java.util.ArrayList; + +/** + * This class is a collection of DataFile objects whit some specific methods. + * + */ +public class DataFiles extends ArrayList +{ + private static final long serialVersionUID = -4584622422555785456L; + + + /** + * + * + */ + public DataFiles() + { + super(); + } + + + /** + * + * @param source + */ + public DataFiles (DataFiles source) + { + super(source); + } + + + + /** + * + */ + public DataFile getByIndex (int index) + { + DataFile result; + + result = (DataFile) super.get (index); + + // + return (result); + } + + /** + * + */ + public DataFile getByName (String name) + { + DataFile result = null; + + if ((name == null) || (name.equals (""))) + { + result = null; + } + else + { + boolean ended = false; + int nDataFile = 0; + while (!ended) + { + if (nDataFile >= this.size()) + { + ended = true; + result = null; + } + else + { + DataFile contentFile = this.getByIndex (nDataFile); + + if (name.equals(contentFile.name())) + { + ended = true; + result = contentFile; + } + else + { + nDataFile += 1; + } + } + } + } + + // + return (result); + } + + /** + * + */ + public DataFile getById (int id) + { + DataFile result = null; + + boolean ended = false; + int nDataFile = 0; + while (!ended) + { + if (nDataFile >= this.size()) + { + ended = true; + result = null; + } + else + { + DataFile contentFile = this.getByIndex (nDataFile); + + if (id == contentFile.id()) + { + ended = true; + result = contentFile; + } + else + { + nDataFile += 1; + } + } + } + + // + return (result); + } + + + /** + * + */ + public DataFiles getByContentId (int id) + { + DataFiles result = new DataFiles(); + + for (int nDataFile = 0; nDataFile < this.size(); nDataFile++) + { + DataFile contentFile = this.getByIndex(nDataFile); + + if (contentFile.contentId() == id) + { + result.add(contentFile); + } + } + + // + return (result); + } + + + /** + * + */ + public String toString() + { + StringBuffer result = new StringBuffer(); + + for (int nDataFile = 0; nDataFile < this.size(); nDataFile++) + { + DataFile contentFile = this.getByIndex(nDataFile); + result.append ("== " + contentFile.name() + "\n"); + result.append ("contentFile " + nDataFile + " - " + contentFile.name() + "\n"); + } + + // + return (result.toString()); + } +} diff --git a/src/fr/devinsy/util/DateHelper.java b/src/fr/devinsy/util/DateHelper.java new file mode 100644 index 0000000..5004c4b --- /dev/null +++ b/src/fr/devinsy/util/DateHelper.java @@ -0,0 +1,351 @@ +/** + * @author Christian Momon, June 2010. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.regex.*; + + +/** + * This class groups function to help in Calendar manipulation. + */ +public class DateHelper +{ + public String LINE_SEPARATOR = "\n"; + + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (DateHelper.class); + + static final String EUROPEAN_DATE_PATTERN = "^([0123]{0,1}\\d)/([01]{0,1}\\d)/(\\d\\d\\d\\d)$"; + static final String RAW_DATE_PATTERN = "^(\\d\\d\\d\\d)([01]\\d)([0123]\\d)$"; + static final String ISO_DATE_PATTERN = "^(\\d\\d\\d\\d)([01]\\d)([0123]\\d)$"; + static final String AMERICAN_DATE_PATTERN = "^([01]{0,1}\\d)/([0123]{0,1}\\d)/(\\d\\d\\d\\d)$"; + + /** + * + */ + static public String europeanFormat (Calendar time) + { + String result; + + if (time == null) + { + result = ""; + } + else + { + result = String.format ("%02d/%02d/%04d", time.get(Calendar.DAY_OF_MONTH), time.get(Calendar.MONTH) + 1, time.get(Calendar.YEAR)); + } + + // + return (result); + } + + + /** + * + */ + static public String ISOFormat (Calendar time) + { + String result; + + if (time == null) + { + result = ""; + } + else + { + result = String.format ("%04d-%02d-%02d", time.get(Calendar.YEAR), time.get(Calendar.MONTH) + 1, time.get(Calendar.DAY_OF_MONTH)); + } + + // + return (result); + } + + + /** + * + */ + public String rawFormat (Calendar time) + { + String result; + + if (time == null) + { + result = ""; + } + else + { + result = String.format ("%02d/%02d/%04d", time.get(Calendar.MONTH) + 1, time.get(Calendar.DAY_OF_MONTH), time.get(Calendar.DAY_OF_MONTH)); + } + + // + return (result); + } + + + /** + * + */ + public String americanFormat (Calendar time) + { + String result; + + if (time == null) + { + result = ""; + } + else + { + result = String.format ("%04d%02d%02d", time.get(Calendar.MONTH), time.get(Calendar.DAY_OF_MONTH) + 1, time.get(Calendar.YEAR)); + } + + // + return (result); + } + + + /** + * + */ + public boolean isValidDate (String date) + { + boolean result; + + if ((isEuropeanFormat (date)) || + (isRawFormat (date)) || + (isISOFormat (date)) || + (isAmericanFormat (date))) + { + result = true; + } + else + { + result = false; + } + + // + return (result); + } + + /** + * + */ + static public boolean isEuropeanFormat (String date) + { + boolean result; + + if (date == null) + { + result = false; + } + else + { + result = date.matches (EUROPEAN_DATE_PATTERN); + } + + // + return (result); + } + + /** + * + */ + static public boolean isRawFormat (String date) + { + boolean result; + + if (date == null) + { + result = false; + } + else + { + result = date.matches (RAW_DATE_PATTERN); + } + + // + return (result); + } + + /** + * + */ + static public boolean isISOFormat (String date) + { + boolean result; + + if (date == null) + { + result = false; + } + else + { + result = date.matches (ISO_DATE_PATTERN); + } + + // + return (result); + } + + /** + * + */ + static public boolean isAmericanFormat (String date) + { + boolean result; + + if (date == null) + { + result = false; + } + else + { + result = date.matches (AMERICAN_DATE_PATTERN); + } + + // + return (result); + } + + + /** + * + */ + static public Calendar parseISODate (String date) + { + Calendar result; + + Pattern pattern = Pattern.compile (ISO_DATE_PATTERN); + Matcher matcher = pattern.matcher (date); + + if ((matcher.find ()) && (matcher.groupCount () == 3)) + { + result = new GregorianCalendar (Integer.parseInt (matcher.group (1)), + Integer.parseInt (matcher.group (2)) - 1, + Integer.parseInt (matcher.group (3))); + } + else + { + result = null; + } + + // + return (result); + } + + + /** + * + */ + static public Calendar parseRawDate (String date) + { + Calendar result; + + Pattern pattern = Pattern.compile (RAW_DATE_PATTERN); + Matcher matcher = pattern.matcher (date); + + if ((matcher.find ()) && (matcher.groupCount () == 3)) + { + result = new GregorianCalendar (Integer.parseInt (matcher.group (1)), + Integer.parseInt (matcher.group (2)) - 1, + Integer.parseInt (matcher.group (3))); + } + else + { + result = null; + } + + // + return (result); + } + + + /** + * + */ + static public Calendar parseAmericanDate (String date) + { + Calendar result; + + Pattern pattern = Pattern.compile (AMERICAN_DATE_PATTERN); + Matcher matcher = pattern.matcher (date); + + if ((matcher.find ()) && (matcher.groupCount () == 3)) + { + result = new GregorianCalendar (Integer.parseInt (matcher.group (3)), + Integer.parseInt (matcher.group (1)) - 1, + Integer.parseInt (matcher.group (2))); + } + else + { + result = null; + } + + // + return (result); + } + + + /** + * + */ + static public Calendar parseEuropeanDate (String date) + { + Calendar result; + + Pattern pattern = Pattern.compile (EUROPEAN_DATE_PATTERN); + Matcher matcher = pattern.matcher (date); + + if ((matcher.find ()) && (matcher.groupCount () == 3)) + { + result = new GregorianCalendar (Integer.parseInt (matcher.group (3)), + Integer.parseInt (matcher.group (2)) - 1, + Integer.parseInt (matcher.group (1))); + } + else + { + result = null; + } + + // + return (result); + } + + + /** + * Note: European parsing test made before the American parsing one. + */ + static public Calendar parseDate (String date) + { + Calendar result; + + if (isEuropeanFormat (date)) + { + result = parseEuropeanDate (date); + } + else if (isRawFormat (date)) + { + result = parseRawDate (date); + } + else if (isISOFormat (date)) + { + result = parseISODate (date); + } + else if (isAmericanFormat (date)) + { + result = parseAmericanDate (date); + } + else + { + result = null; + } + + // + return (result); + } +} diff --git a/src/fr/devinsy/util/Digester.java b/src/fr/devinsy/util/Digester.java new file mode 100644 index 0000000..9d8f14d --- /dev/null +++ b/src/fr/devinsy/util/Digester.java @@ -0,0 +1,113 @@ +/* + * @author Christian Momon, 2006-2010 + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + * + */ +package fr.devinsy.util; + +import java.io.*; +import java.io.File; +import java.security.*; + + +/** + * This class is a helper to use MessageDigester class. + */ +public class Digester +{ + /** + * + */ + static public String humanReadableDigest (byte[] digest) + { + String result; + + StringBuffer hashString = new StringBuffer (); + + for (int letterIndex = 0; letterIndex < digest.length; ++letterIndex) + { + String hex = Integer.toHexString (digest[letterIndex]); + if (hex.length() == 1) + { + hashString.append ('0'); + hashString.append (hex.charAt (hex.length () - 1)); + } + else + { + hashString.append (hex.substring (hex.length () - 2)); + } + } + + result = hashString.toString(); + + // + return (result); + } + + + /** + * "SHA-1", "MD5", "SHA-256", and "SHA-512" + */ + static public String computeHash (String digestMethod, File file) throws Exception + { + String result; + + if ((file == null) || (!file.exists())) + { + result = null; + } + else + { + //byte[] hash = null; + + InputStream source = null; + try + { + MessageDigest digester = MessageDigest.getInstance (digestMethod); + source = new FileInputStream (file); + boolean ended = false; + int bytesNumber; + byte[] buffer = new byte[100*1024]; + while (!ended) + { + bytesNumber = source.read (buffer); + if (bytesNumber == -1) + { + ended = true; + } + else + { + digester.update (buffer, 0, bytesNumber); + } + } + + byte[] digest = digester.digest (); + + result = humanReadableDigest (digest); + } + catch (java.security.NoSuchAlgorithmException exception) + { + throw new Exception("Digest method unknown.", exception); + } + catch (java.io.FileNotFoundException exception) + { + throw new Exception("Digest method unknown.", exception); + } + catch (java.io.IOException exception) + { + throw new Exception("Error reading file.", exception); + } + finally + { + if (source != null) + { + source.close(); + } + } + } + + // + return (result); + } +} diff --git a/src/fr/devinsy/util/FileIterator.java b/src/fr/devinsy/util/FileIterator.java new file mode 100644 index 0000000..2acb34d --- /dev/null +++ b/src/fr/devinsy/util/FileIterator.java @@ -0,0 +1,100 @@ +package fr.devinsy.util; + +import java.io.File; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + + +/** + * + */ +public class FileIterator implements Iterator +{ + static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (FileIterator.class); + + protected FileIteratorStates states; + protected File previous; + protected String filter; + protected Pattern pattern; + + /** + * + */ + public FileIterator (File root) + { + this.states = new FileIteratorStates(root); + this.previous = null; + this.filter = null; + this.pattern = null; + } + + + /** + * TODO + */ + public FileIterator (File root, String filter) + { + this.states = new FileIteratorStates(root); + this.previous = null; + + this.filter = filter; + this.pattern = Pattern.compile(filter); + } + + + /** + * + */ + @Override + public boolean hasNext() + { + boolean result; + + result = this.states.hasNext(); + + // + return(result); + } + + + /** + * + */ + @Override + public File next() + { + File result; + + result = this.states.next(); + this.previous = result; + + // + return(result); + } + + + @Override + public void remove() + { + if (this.previous != null) + { + this.previous.delete(); + this.previous = null; + } + } + + /** + * + */ + public String toString() + { + String result; + + result = "[depth=" + this.states.currentDepth + "][index=" + this.states.get(this.states.currentDepth).currentIndex() + "/" + this.states.get(this.states.currentDepth).files.length + "]"; + + // + return(result); + } +} diff --git a/src/fr/devinsy/util/FileIteratorState.java b/src/fr/devinsy/util/FileIteratorState.java new file mode 100644 index 0000000..bb6ae82 --- /dev/null +++ b/src/fr/devinsy/util/FileIteratorState.java @@ -0,0 +1,119 @@ +package fr.devinsy.util; + +import java.io.File; + + + +/** + * + */ +public class FileIteratorState +{ + protected File[] files; + protected int currentIndex; + + /** + * + */ + public FileIteratorState (File file) + { + if (file.isDirectory()) + { + this.files = file.listFiles(); + this.currentIndex = 0; + } + else + { + // File case or not exist file. + this.files = new File[1]; + this.files[0] = file; + this.currentIndex = 0; + } + } + + + /** + * + */ + protected File[] files() + { + File[] result; + + result = this.files; + + // + return(result); + } + + + /** + * + */ + protected int currentIndex() + { + int result; + + result = this.currentIndex; + + // + return(result); + } + + + /** + * + */ + protected File currentFile() + { + File result; + + if (this.currentIndex >= this.files.length) + { + result = null; + } + else + { + result = this.files[this.currentIndex]; + } + + // + return(result); + } + + + /** + * + */ + public boolean hasNext() + { + boolean result; + + + if (this.currentIndex >= this.files.length) + { + result = false; + } + else + { + result = true; + } + + // + return(result); + } + + + /** + * + */ + public File next() + { + File result; + + result = this.currentFile(); + this.currentIndex += 1; + + // + return(result); + } +} diff --git a/src/fr/devinsy/util/FileIteratorStates.java b/src/fr/devinsy/util/FileIteratorStates.java new file mode 100644 index 0000000..1ca8f83 --- /dev/null +++ b/src/fr/devinsy/util/FileIteratorStates.java @@ -0,0 +1,133 @@ +package fr.devinsy.util; + +import java.io.File; +import java.util.Vector; + + + +/** + * + */ +public class FileIteratorStates extends Vector +{ + private static final long serialVersionUID = 8790133455427427766L; + + protected int currentDepth;; + + + /** + * + */ + public FileIteratorStates (File root) + { + super(); + + this.currentDepth = -1; // Note: push method increments this value. + if (root != null) + { + this.push(root); + } + } + + + /** + * + */ + protected FileIteratorState currentState() + { + FileIteratorState result; + + result = this.get(this.currentDepth); + + // + return(result); + } + + + /** + * + */ + protected File currentFile() + { + File result; + + result = this.currentState().currentFile(); + + // + return(result); + } + + + /** + * + */ + public void push(File directory) + { + this.add(new FileIteratorState(directory)); + this.currentDepth += 1; + } + + + /** + * + */ + public void pop() + { + this.removeElementAt(this.currentDepth); + this.currentDepth -= 1; + } + + + /** + * + */ + public boolean hasNext() + { + boolean result; + + result = this.currentState().hasNext(); + + // + return(result); + } + + + /** + * + */ + public File next() + { + File result; + + result = this.currentState().next(); + + if (result.isDirectory()) + { + this.push(result); + } + + // Up states if needed. + boolean ended = false; + while(!ended) + { + if (this.hasNext()) + { + ended = true; + } + else + { + if (this.currentDepth == 0) + { + ended = true; + } + else + { + this.pop(); + } + } + } + + // + return(result); + } +} diff --git a/src/fr/devinsy/util/Fraction.java b/src/fr/devinsy/util/Fraction.java new file mode 100644 index 0000000..ce5bc4b --- /dev/null +++ b/src/fr/devinsy/util/Fraction.java @@ -0,0 +1,186 @@ +/** + * Fraction class. Useful for display beautiful percentage value as string. + * + * @author Christian Momon, September 2009. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + + +/** + * + * */ +public class Fraction +{ + protected long numerator; + protected long denominator; + + + /** + * + */ + public Fraction(long numerator, long denominator) + { + this.numerator = numerator; + this.denominator = denominator; + } + + + /** + * + */ + public long numerator() + { + long result; + + result = this.numerator; + + // + return (result); + } + + + /** + * + */ + public long denominator() + { + long result; + + result = this.denominator; + + // + return (result); + } + + /** + * + */ + public long percentage() throws Exception + { + long result; + + result = percentage(this.numerator, this.denominator); + + // + return (result); + } + + + /** + * + */ + static public long percentage(long numerator, long denominator) throws Exception + { + long result; + + if (denominator == 0) + { + throw new Exception("denominator is zero"); + } + else + { + result = Math.round(numerator * 100 / denominator); + } + + // + return (result); + } + + + /** + * + */ + static public String percentageString(long numerator, long denominator) + { + String result; + + try + { + long value = percentage(numerator, denominator); + + if (numerator == 0) + { + result = "0%"; + } + else if (value == 0) + { + result = "~0%"; + } + else if (value < 10) + { + result = "0" + value + "%"; + } + else + { + result = value + "%"; + } + } + catch (Exception exception) + { + result = "--%"; + } + + + // + return (result); + } + + + /** + * + */ + public String percentageString() + { + String result; + + result = percentageString(this.numerator, this.denominator); + + // + return (result); + } + + + /** + * + */ + static public String percentageFullString(long numerator, long denominator) + { + String result; + + result = percentageString(numerator, denominator); + + // + return (result); + } + + + /** + * + */ + public String percentageFullString() + { + String result; + + result = percentageFullString(this.numerator, this.denominator); + + // + return (result); + } + + + + /** + * + */ + public String toString() + { + String result; + + result = this.numerator + "/" + this.denominator; + + // + return(result); + } +} diff --git a/src/fr/devinsy/util/InternetProxyConfiguration.java b/src/fr/devinsy/util/InternetProxyConfiguration.java new file mode 100644 index 0000000..3d0c41d --- /dev/null +++ b/src/fr/devinsy/util/InternetProxyConfiguration.java @@ -0,0 +1,236 @@ +/** + * @author Christian Momon, September 2009. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + + +/** + * + */ +public class InternetProxyConfiguration +{ + // + protected String host; + protected int port; + protected String login; + protected String password; + + /** + * + */ + public InternetProxyConfiguration () + { + this.host = ""; + this.port = 0; + this.login = ""; + this.password = ""; + } + + + /** + * + */ + public InternetProxyConfiguration (String host, String port, String login, String password) throws Exception + { + // + if (host == null) + { + this.host = ""; + } + else + { + this.host = host; + } + + // + if ((port == null) || (port.trim().length() == 0)) + { + this.port = 0; + } + else + { + try + { + this.port = Integer.parseInt (port); + } + catch (Exception exception) + { + String errorMessage = "Incorrect PROXY port value."; + throw new Exception (errorMessage, exception); + } + } + + // + if (login == null) + { + this.login = ""; + } + else + { + this.login = login; + } + + // + if (password == null) + { + this.password = ""; + } + else + { + this.password = password; + } + } + + + /** + * + */ + public InternetProxyConfiguration (String host, int port, String login, String password) + { + // + if (host == null) + { + this.host = ""; + } + else + { + this.host = host; + } + + // + this.port = port; + + // + if (login == null) + { + this.login = ""; + } + else + { + this.login = login; + } + + // + if (password == null) + { + this.password = ""; + } + else + { + this.password = password; + } + } + + + /** + * + */ + public String host() + { + String result; + + result = this.host; + + // + return (result); + } + + + /** + * + */ + public int port() + { + int result; + + result = this.port; + + // + return (result); + } + + + /** + * + */ + public String login() + { + String result; + + result = this.login; + + // + return (result); + } + + + /** + * + */ + public String password() + { + String result; + + result = this.password; + + // + return (result); + } + + + /** + * + */ + public boolean isInitialized() + { + boolean result; + + if ((this.host.length() > 0) && (this.port > 0)) + { + result = true; + } + else + { + result = false; + } + + // + return(result); + } + + + /** + * + */ + public String toString() + { + String result; + + String login; + if (this.login.length() == 0) + { + login = ""; + } + else + { + login = "********"; + } + + String password; + if (this.password.length() == 0) + { + password = ""; + } + else + { + password = "********"; + } + + result = "(" + this.host + "," + this.port + "," + login + "," + password + ")"; + + // + return (result); + } +} diff --git a/src/fr/devinsy/util/SimpleAveragemeter.java b/src/fr/devinsy/util/SimpleAveragemeter.java new file mode 100644 index 0000000..38d64d8 --- /dev/null +++ b/src/fr/devinsy/util/SimpleAveragemeter.java @@ -0,0 +1,125 @@ +/** + * @author Christian Momon, September 2009. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + +/** + * This class defines a simple average manager. For example, it is useful for millisecond. + * The maximum value available in input is one day in millisecond. + */ +public class SimpleAveragemeter +{ + // + protected long sum; + protected long cardinal; + protected long MAX_ADD = 1*24*60*60*1000; // One day in millisecond. + + /** + * + */ + public SimpleAveragemeter () + { + this.reset(); + } + + + /** + * + */ + synchronized public void reset() + { + this.sum = 0; + this.cardinal = 0; + } + + + /** + * + */ + synchronized public long average() + { + long result; + + if (cardinal == 0) + { + result = 0; + } + else + { + result = (long) sum/cardinal; + } + + // + return(result); + } + + + /** + * + */ + public long value() + { + long result; + + result = this.average(); + + // + return(result); + } + + + /** + * + */ + public long cardinal() + { + long result; + + result = this.cardinal; + + // + return(result); + } + + + /** + * + */ + synchronized public void add(long value) + { + // Manage the sum limit. + if ((this.sum > Long.MAX_VALUE/2) && (cardinal%2 == 0)) + { + this.sum = (long) this.sum /2; + this.cardinal = this.cardinal/2; + } + + // Add the new value. + if (this.sum > MAX_ADD) + { + this.sum += MAX_ADD; + this.cardinal += 1; + } + else + { + this.sum += value; + this.cardinal += 1; + } + } + + + /** + * + */ + public String toString() + { + String result; + + result = Long.toString(this.average()); + + // + return (result); + } +} diff --git a/src/fr/devinsy/util/SimpleChronometer.java b/src/fr/devinsy/util/SimpleChronometer.java new file mode 100644 index 0000000..c172db6 --- /dev/null +++ b/src/fr/devinsy/util/SimpleChronometer.java @@ -0,0 +1,50 @@ +/** + * @author Christian Momon, in June 2008. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + +import java.util.Date; + + +/** + * + */ +public class SimpleChronometer +{ + // + protected long firstTime; + + + /** + * + */ + public SimpleChronometer () + { + this.reset(); + } + + + /** + * + */ + public void reset() + { + this.firstTime = new Date().getTime(); + } + + + /** + * + */ + public long interval() + { + long result; + + result = new Date().getTime() - this.firstTime; + + // + return(result); + } +} diff --git a/src/fr/devinsy/util/StacktraceWriter.java b/src/fr/devinsy/util/StacktraceWriter.java new file mode 100644 index 0000000..8bc2f98 --- /dev/null +++ b/src/fr/devinsy/util/StacktraceWriter.java @@ -0,0 +1,25 @@ +package fr.devinsy.util; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +/** + * + */ +public class StacktraceWriter +{ + /** + * + */ + static public String toString(Exception exception) + { + String result; + + ByteArrayOutputStream out = new ByteArrayOutputStream(50000); + exception.printStackTrace(new PrintStream(out)); + result = out.toString(); + + // + return (result); + } +} diff --git a/src/fr/devinsy/util/StringConcatenator.java b/src/fr/devinsy/util/StringConcatenator.java new file mode 100644 index 0000000..085f464 --- /dev/null +++ b/src/fr/devinsy/util/StringConcatenator.java @@ -0,0 +1,398 @@ +/** + * @author Christian Momon, June 2008. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + +import java.io.IOException; +import java.util.ArrayList; + +/** + * This class is a collection of String objects with specific methods. + * It makes possible to build a string without any copy. + * The goal is to optimize the building of strings where they are lot of concatenation action. + */ +public class StringConcatenator extends ArrayList +{ + private static final long serialVersionUID = -1154185934830213732L; + public String LINE_SEPARATOR = "\n"; + + /** + * + */ + public StringConcatenator () + { + super(); + } + + + /** + * + */ + public String getByIndex(int id) + { + String result; + + result = (String) this.get(id); + + // + return (result); + } + + + /** + * + */ + public StringConcatenator appendln() + { + StringConcatenator result; + + this.add(LINE_SEPARATOR); + + result = this; + + // + return(result); + } + + + /** + * + */ + public StringConcatenator append(String string) + { + StringConcatenator result; + + if (string != null) + { + this.add(string); + } + + result = this; + + // + return(result); + } + + + /** + * + */ + public StringConcatenator appendln(String string) + { + StringConcatenator result; + + result = this.append(string).appendln(); + + // + return(result); + } + + + /** + * + */ + public StringConcatenator append(char character) + { + StringConcatenator result; + + this.add(String.valueOf(character)); + + result = this; + + // + return(result); + } + + + /** + * + */ + public StringConcatenator appendln(char character) + { + StringConcatenator result; + + result = this.append(character).appendln(); + + // + return(result); + } + + + /** + * + */ + public StringConcatenator append(StringConcatenator string) + { + StringConcatenator result; + + if (string != null) + { + for (int nString = 0; nString < string.size(); nString++) + { + this.add(string.getByIndex(nString)); + } + } + + result = this; + + // + return(result); + } + + /** + * + */ + public StringConcatenator appendln(StringConcatenator string) + { + StringConcatenator result; + + result = this.append(string).appendln(); + + // + return(result); + } + + /** + * + */ + public void writeInto(java.io.Writer out) throws IOException + { + for (int nString = 0; nString < this.size(); nString++) + { + out.write(this.getByIndex(nString)); + } + } + + + /** + * + */ + public int lenght() + { + int result = 0; + + for (int nString = 0; nString < this.size(); nString++) + { + result += this.getByIndex(nString).length(); + + } + + // + return(result); + } + + + /** + * + */ + public String toString() + { + String result; + + StringBuffer preResult = new StringBuffer(this.lenght()); + + for (int nString = 0; nString < this.size(); nString++) + { + preResult.append(this.getByIndex(nString)); + } + + result = new String(preResult); + + // + return(result); + } + + + /** + * + */ + static public String toString(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator string = new StringConcatenator(); + + for (int nString = 0; nString < strings.length; nString++) + { + string.append(strings[nString]); + + if (nString < strings.length - 1) + { + string.append(' '); + } + } + + result = string.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringNotNull(String[] strings) + { + String result; + + result = toString(strings); + + if (result == null) + { + result = ""; + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithBracket(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator merge = new StringConcatenator(); + + merge.append("["); + merge.append(toStringWithCommas(strings)); + merge.append("]"); + + result = merge.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithCommas(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator merge = new StringConcatenator(); + + for (String string : strings) + { + if (merge.size() != 0) + { + merge.append(","); + } + + merge.append(string); + } + + result = merge.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithFrenchCommas(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator merge = new StringConcatenator(); + + for (String string : strings) + { + if (merge.size() != 0) + { + merge.append(", "); + } + + merge.append(string); + } + + result = merge.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithBrackets(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator merge = new StringConcatenator(); + + for (String string : strings) + { + merge.append("[").append(string).append("]"); + } + + result = merge.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithBracketNotNull(String[] strings) + { + String result; + + result = toStringWithBrackets(strings); + + if (result == null) + { + result = ""; + } + + // + return(result); + } +} diff --git a/src/fr/devinsy/util/StringList.java b/src/fr/devinsy/util/StringList.java new file mode 100644 index 0000000..bb2f48e --- /dev/null +++ b/src/fr/devinsy/util/StringList.java @@ -0,0 +1,448 @@ +/** + * @author Christian Momon, June 2008. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + +import java.io.IOException; +import java.util.ArrayList; + +/** + * This class is a collection of String objects with specific methods. + * It makes possible to build a string without any copy. + * The goal is to optimize the building of strings where they are lot of concatenation action. + */ +public class StringList extends ArrayList +{ + private static final long serialVersionUID = -1154185934830213732L; + public String LINE_SEPARATOR = "\n"; + + /** + * + */ + public StringList () + { + super(); + } + + + /** + * + */ + public StringList (int size) + { + super(size); + } + + + /** + * + */ + public String getByIndex(int id) + { + String result; + + result = (String) this.get(id); + + // + return (result); + } + + + /** + * + */ + public StringList appendln() + { + StringList result; + + this.add(LINE_SEPARATOR); + + result = this; + + // + return(result); + } + + + /** + * Check null parameter before add. + */ + public StringList append(String string) + { + StringList result; + + if (string != null) + { + this.add(string); + } + + result = this; + + // + return(result); + } + + + /** + * + */ + public StringList appendln(String string) + { + StringList result; + + result = this.append(string).appendln(); + + // + return(result); + } + + + /** + * + */ + public StringList append(char character) + { + StringList result; + + this.add(String.valueOf(character)); + + result = this; + + // + return(result); + } + + + /** + * + */ + public StringList appendln(char character) + { + StringList result; + + result = this.append(character).appendln(); + + // + return(result); + } + + + /** + * + */ + public StringList appendln(int value) + { + StringList result; + + result = this.append(String.valueOf(value)).appendln(); + + // + return(result); + } + + + /** + * + */ + public StringList appendln(long value) + { + StringList result; + + result = this.append(String.valueOf(value)).appendln(); + + // + return(result); + } + + + /** + * + */ + public StringList append(StringList string) + { + StringList result; + + if (string != null) + { + for (int nString = 0; nString < string.size(); nString++) + { + this.add(string.getByIndex(nString)); + } + } + + result = this; + + // + return(result); + } + + /** + * + */ + public StringList appendln(StringList string) + { + StringList result; + + result = this.append(string).appendln(); + + // + return(result); + } + + /** + * + */ + public void writeInto(java.io.Writer out) throws IOException + { + for (int nString = 0; nString < this.size(); nString++) + { + out.write(this.getByIndex(nString)); + } + } + + + /** + * + */ + public int lenght() + { + int result = 0; + + for (int nString = 0; nString < this.size(); nString++) + { + result += this.getByIndex(nString).length(); + + } + + // + return(result); + } + + + /** + * + */ + public String toString() + { + String result; + + StringBuffer preResult = new StringBuffer(this.lenght()); + + for (int nString = 0; nString < this.size(); nString++) + { + preResult.append(this.getByIndex(nString)); + } + + result = new String(preResult); + + // + return(result); + } + + + /** + * + */ + public void removeLast() + { + if (this.size() > 0) + { + this.remove(this.size() - 1); + } + } + + + + /** + * + */ + static public String toString(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator string = new StringConcatenator(); + + for (int nString = 0; nString < strings.length; nString++) + { + string.append(strings[nString]); + + if (nString < strings.length - 1) + { + string.append(' '); + } + } + + result = string.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringNotNull(String[] strings) + { + String result; + + result = toString(strings); + + if (result == null) + { + result = ""; + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithBracket(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator merge = new StringConcatenator(); + + merge.append("["); + merge.append(toStringWithCommas(strings)); + merge.append("]"); + + result = merge.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithCommas(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator merge = new StringConcatenator(); + + for (String string : strings) + { + if (merge.size() != 0) + { + merge.append(","); + } + + merge.append(string); + } + + result = merge.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithFrenchCommas(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator merge = new StringConcatenator(); + + for (String string : strings) + { + if (merge.size() != 0) + { + merge.append(", "); + } + + merge.append(string); + } + + result = merge.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithBrackets(String[] strings) + { + String result; + + if (strings == null) + { + result = null; + } + else + { + StringConcatenator merge = new StringConcatenator(); + + for (String string : strings) + { + merge.append("[").append(string).append("]"); + } + + result = merge.toString(); + } + + // + return(result); + } + + + /** + * + */ + static public String toStringWithBracketNotNull(String[] strings) + { + String result; + + result = toStringWithBrackets(strings); + + if (result == null) + { + result = ""; + } + + // + return(result); + } +} diff --git a/src/fr/devinsy/util/StringListWriter.java b/src/fr/devinsy/util/StringListWriter.java new file mode 100644 index 0000000..f2a475d --- /dev/null +++ b/src/fr/devinsy/util/StringListWriter.java @@ -0,0 +1,82 @@ +/** + * @author Christian Momon, March 2010. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ +package fr.devinsy.util; + +import java.io.IOException; +import java.io.Writer; + + +/** + * + */ +public class StringListWriter extends Writer +{ + protected StringList out; + + + /** + * + */ + StringListWriter() + { + this.out = new StringList(); + } + + + /** + * + */ + StringListWriter(int size) + { + this.out = new StringList(size); + } + + + /* + * + */ + @Override + public void close() throws IOException + { + + } + + /* + * + */ + @Override + public void flush() throws IOException + { + + } + + /* + * + */ + @Override + public void write(char[] cbuf, int off, int len) throws IOException + { + this.out.append(cbuf.toString().substring(off, len)); + } + + + /* + * + */ + public void write(char c) throws IOException + { + this.out.append(c); + } + + + /* + * + */ + public void write(String string) throws IOException + { + this.out.append(string); + } +} diff --git a/src/fr/devinsy/util/cmdexec/CmdExec.java b/src/fr/devinsy/util/cmdexec/CmdExec.java new file mode 100644 index 0000000..dd3095d --- /dev/null +++ b/src/fr/devinsy/util/cmdexec/CmdExec.java @@ -0,0 +1,453 @@ +package fr.devinsy.util.cmdexec; + +import fr.devinsy.util.StringConcatenator; + + + +/** + * We must use the isOver method on Gobblers because with short tasks the waitFor ends before the Gobbler read. + */ +public class CmdExec +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (CmdExec.class); + + protected int exitValue; + protected String out; + protected String err; + + + // //////////////////////////////////////////////////////////////////// + // + // //////////////////////////////////////////////////////////////////// + + /** + * + */ + public CmdExec (String command) + { + run (command, StreamGobbler.NONE, StreamGobbler.NONE); + } + + + /** + * + */ + public CmdExec (String ... command) + { + run (command, StreamGobbler.NONE, StreamGobbler.NONE); + } + + + /** + * + */ + public CmdExec (String command, int STDOUT, int STDERR) + { + run (command, STDOUT, STDERR); + } + + + /** + * + */ + public CmdExec (String[] command, int STDOUT, int STDERR) + { + run (command, STDOUT, STDERR); + } + + + /** + * + */ + public CmdExec (String command, StreamGobbler outputGobbler, StreamGobbler errorGobbler) + { + run (command, outputGobbler, errorGobbler); + } + + + /** + * + */ + public CmdExec (String[] command, StreamGobbler outputGobbler, StreamGobbler errorGobbler) + { + run (command, outputGobbler, errorGobbler); + } + + + // //////////////////////////////////////////////////////////////////// + // + // //////////////////////////////////////////////////////////////////// + + /** + * + */ + public int run (String command, int STDOUT, int STDERR) + { + int result; + + result = run (command, + new StreamGobbler ("OUTPUT", STDOUT), + new StreamGobbler ("ERROR", STDERR)); + + // + return (result); + } + + + // + public int run (String[] command, int STDOUT, int STDERR) + { + int result; + + result = run (command, + new StreamGobbler ("OUTPUT", STDOUT), + new StreamGobbler ("ERROR", STDERR)); + + // + return (result); + } + + + /** + * Command: not a shell command, it must be a executable program. + */ + public int run (String[] command, StreamGobbler outputGobbler, StreamGobbler errorGobbler) + { + this.exitValue = 0; + + logger.info ("CmdExec(commande[]) = [" + StringConcatenator.toString(command) + "]"); + logger.info ("CmdExec(commande[]) = [" + StringConcatenator.toStringWithBrackets(command) + "]"); + + try + { + Runtime rt = Runtime.getRuntime (); + + Process proc = rt.exec(command); + + // Any error message? + errorGobbler.setInputStream (proc.getErrorStream ()); + + // Any output? + outputGobbler.setInputStream (proc.getInputStream ()); + + // Kick them off + errorGobbler.start (); + outputGobbler.start (); + + + // Any error??? + this.exitValue = proc.waitFor (); + logger.info("ExitValue: " + exitValue); + + // Sometimes, process ends before Gobblers read its outpout, so we must wait them. + while ((!outputGobbler.isOver ()) || + (!errorGobbler.isOver ())) + { + Thread.sleep (2); + } + + out = outputGobbler.getStream (); + err = errorGobbler.getStream (); + } + catch (Exception exception) + { + this.err = exception.getMessage(); + this.exitValue = -77; + exception.printStackTrace (); + } + + // + return (this.exitValue); + } + + + /** + * + * @param command: not a shell command, it must be a executable program. + * @param outputGobbler + * @param errorGobbler + * @return + */ + public int run (String command, StreamGobbler outputGobbler, StreamGobbler errorGobbler) + { + int result; + + logger.info ("CmdExec(commande) = [" + command + "]"); + + String[] commands = command.split("[ \t\n\r\f]"); + + result = run(commands, outputGobbler, errorGobbler); + + // + return(result); + } + + + /** + * + * @return + */ + public int getExitValue () + { + int result; + + result = this.exitValue; + + return (result); + } + + + /** + * + * @return + */ + public String getOutStream () + { + String result; + + result = this.out; + + // + return (result); + } + + + /** + * + * @return + */ + public String getErrStream () + { + String result; + + result = this.err; + + // + return (result); + } + + // //////////////////////////////////////////////////////////////////// + // + // //////////////////////////////////////////////////////////////////// + /** + * + */ + static public String run (String command) throws Exception + { + String result; + + result = CmdExec.run(command.split("[ \t\n\r\f]")); + + // + return(result); + } + + + /** + * + */ + static public String run (String ... command) throws Exception + { + String result; + + if ((command == null) || (command.length == 0)) + { + throw new Exception("Empty command"); + } + else + { + CmdExec cmd = new CmdExec (command, + StreamGobbler.BUFFER, + StreamGobbler.BUFFER); + + if (cmd.getExitValue() == 0) + { + result = cmd.getOutStream(); + } + else + { + logger.error("Command=\"" + StringConcatenator.toStringWithBrackets(command)); + logger.error("Command=\"[" + StringConcatenator.toString(command) + "]\n out => [" + cmd.getOutStream() + "]\n " + "err => (" + cmd.getErrStream().length () +")[" + cmd.getErrStream() + "]"); + throw new Exception(cmd.getErrStream()); + } + } + + // + return (result); + } + + + /** + * Examples: + * setfacl("setfacl", "-m", "g:cpm:rwX", "/tmp/toto"); + * setfacl("setfacl", "-R", "-m", "g:cpm:rwX", "/tmp/toto"); + */ + static public String run (String program, String[] args, int min, int max) throws Exception + { + String result; + + // + boolean nullArg = false; + boolean ended = false; + int nArg = 0; + while (!ended) + { + if (nArg >= args.length) + { + ended = true; + nullArg = false; + } + else + { + if (args[nArg] == null) + { + ended = true; + nullArg = true; + } + else + { + nArg += 1; + } + } + } + + // + if (program == null) + { + throw new Exception ("Null program parameter detected: [" + program + "]."); + } + else if (nullArg) + { + throw new Exception ("Null parameter detected in position " + nArg + " for " + StringConcatenator.toStringWithBrackets(args) + "."); + } + else if ((args.length < min) || (args.length > max)) + { + throw new Exception ("Bad number of parameters: " + args.length + " for " + StringConcatenator.toStringWithBrackets(args) + "."); + } + else + { + // + String[] command = new String[args.length + 1]; + command[0] = program; + for (nArg = 0; nArg < args.length; nArg++) + { + command[nArg + 1] = args[nArg]; + } + + result = CmdExec.run (command); + } + + // + return(result); + } + + + /** + * Examples: + * setfacl("sudo", "setfacl", "-m", "g:cpm:rwX", "/tmp/toto"); + * setfacl("sudo", "setfacl", "-R", "-m", "g:cpm:rwX", "/tmp/toto"); + */ + static public String run (String program1, String program2, String[] args, int min, int max) throws Exception + { + String result; + + // + boolean nullArg = false; + boolean ended = false; + int nArg = 0; + while (!ended) + { + if (nArg >= args.length) + { + ended = true; + nullArg = false; + } + else + { + if (args[nArg] == null) + { + ended = true; + nullArg = true; + } + else + { + nArg += 1; + } + } + } + + // + if (program1 == null) + { + throw new Exception ("Null program parameter 1 detected: [" + program1 + "]."); + } + else if (program2 == null) + { + throw new Exception ("Null program parameter 2 detected: [" + program2 + "]."); + } + else if (nullArg) + { + throw new Exception ("Null parameter detected in position " + nArg + " for " + StringConcatenator.toStringWithBrackets(args) + "."); + } + else if ((args.length < min) || (args.length > max)) + { + throw new Exception ("Bad number of parameters: " + args.length + " for " + StringConcatenator.toStringWithBrackets(args) + "."); + } + else + { + // + String[] command = new String[args.length + 2]; + command[0] = program1; + command[1] = program2; + for (nArg = 0; nArg < args.length; nArg++) + { + command[nArg + 2] = args[nArg]; + } + + result = CmdExec.run (command); + } + + // + return(result); + } + + + /** + * + */ + static public String multirun (String ... commands) throws Exception + { + String result; + + result = ""; + + boolean ended = false; + int commandCounter = 0; + while (!ended) + { + if (commandCounter < commands.length) + { + String command = commands[commandCounter]; + + if ((command == null) || (command.length () == 0)) + { + result = null; + commandCounter += 1; + } + else + { + result += CmdExec.run (command); + commandCounter += 1; + } + } + else + { + ended = true; + result = null; + } + } + + // + return (result); + } +} diff --git a/src/fr/devinsy/util/cmdexec/StreamGobbler.java b/src/fr/devinsy/util/cmdexec/StreamGobbler.java new file mode 100644 index 0000000..37b9af6 --- /dev/null +++ b/src/fr/devinsy/util/cmdexec/StreamGobbler.java @@ -0,0 +1,142 @@ +package fr.devinsy.util.cmdexec; + +import java.io.*; + + +/** + * + */ +public class StreamGobbler extends Thread +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (CmdExec.class); + + static final public int NONE = 0; + static final public int PRINT = 1; + static final public int BUFFER = 2; + + protected InputStream is; + protected String type; + protected int streamWay; + protected StringBuffer stream; + protected boolean isOverStatus; // Important if the caller wants have complete stream in case of very short command. + + + // + StreamGobbler () + { + this.type = ""; + this.streamWay = NONE; + this.stream = new StringBuffer (); + this.isOverStatus = false; + } + + + // + StreamGobbler (String type, int streamWay) + { + this.type = type; + this.streamWay = streamWay; + this.stream = new StringBuffer (); + this.isOverStatus = false; + } + + + // + StreamGobbler (InputStream is, String type) + { + this.is = is; + this.type = type; + this.streamWay = NONE; + this.stream = new StringBuffer (); + this.isOverStatus = false; + } + + + // + StreamGobbler (InputStream is, String type, int streamWay) + { + this.is = is; + this.type = type; + this.streamWay = streamWay; + this.stream = new StringBuffer (); + this.isOverStatus = false; + } + + + // + public void setInputStream (InputStream is) + { + this.is = is; + } + + + // + public void run () + { + try + { + InputStreamReader isr = new InputStreamReader (is); + BufferedReader br = new BufferedReader (isr); + String line = null; + if (this.streamWay == NONE) + { + while ((line = br.readLine ()) != null); + } + else if (this.streamWay == PRINT) + { + while ((line = br.readLine ()) != null) + { + System.out.println (type + ">" + line); + } + } + else if (this.streamWay == BUFFER) + { + while ((line = br.readLine ()) != null) + { + stream.append (line + "\n"); + } + } + else + { + logger.warn("unknow way for stream"); + } + } + catch (IOException ioe) + { + ioe.printStackTrace (); + } + + this.isOverStatus = true; + } + + + // + public String getStream () + { + String result; + + if (this.stream != null) + { + result = this.stream.toString (); + } + else + { + result = null; + } + + // + return (result); + } + + + // + public boolean isOver () + { + boolean result; + + result = this.isOverStatus; + + // + return (result); + } +} diff --git a/src/fr/devinsy/util/cmdexec/Wrapper.java b/src/fr/devinsy/util/cmdexec/Wrapper.java new file mode 100644 index 0000000..9e4ce55 --- /dev/null +++ b/src/fr/devinsy/util/cmdexec/Wrapper.java @@ -0,0 +1,69 @@ +package fr.devinsy.util.cmdexec; + +import java.io.*; + + +/** + * + */ +public class Wrapper +{ + static private final Wrapper instance = new Wrapper (); + static private org.apache.log4j.Logger logger; + + static + { + logger = org.apache.log4j.Logger.getLogger (Wrapper.class); + } + + /** + * return instance of the controller + */ + public static Wrapper instance () + { + return (instance); + } + + + /** + * + */ + static public void wrap (String ressource, PrintWriter output) throws IOException + { + logger.info ("Enter"); + + BufferedReader buf = new BufferedReader (new FileReader (ressource)); + String ligne; + while ((ligne = buf.readLine()) != null) + { + output.print (ligne); + } + + logger.info ("Exit"); + } + + + /** + * + */ + static public StringBuffer wrap (String ressource) throws IOException + { + logger.info ("Enter"); + StringBuffer result; + + result = new StringBuffer (); + + BufferedReader buf = new BufferedReader (new FileReader (ressource)); + String ligne; + while ((ligne = buf.readLine()) != null) + { + result.append (ligne + "\n"); + } + + // + logger.info ("Exit"); + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/CachedFile.java b/src/fr/devinsy/util/unix/CachedFile.java new file mode 100644 index 0000000..7e24730 --- /dev/null +++ b/src/fr/devinsy/util/unix/CachedFile.java @@ -0,0 +1,124 @@ +package fr.devinsy.util.unix; + +import java.io.*; + + + +/** + * + */ +public class CachedFile +{ + static private org.apache.log4j.Logger logger; + static + { + logger = org.apache.log4j.Logger.getLogger (CachedFile.class); + } + + public enum Status {NOT_LOAD, EXPIRED, UPDATED}; + + protected String sourceName; + protected long sourceTime; + protected Status status; + + /** + * + */ + public CachedFile (String fileName) + { + this.sourceName = fileName; + this.sourceTime = 0; + this.status = Status.NOT_LOAD; + } + + + /** + * + */ + protected File getSourceFile () + { + File result; + + if (this.sourceName == null) + { + result = null; + } + else + { + File source = new File (this.sourceName); + + if (source == null) + { + logger.error ("source file not defined (" + this.sourceName + ")"); + result = null; + } + else if (!source.exists ()) + { + logger.error ("source file defined but not found"); + result = null; + } + else + { + result = source; + } + } + + // + return (result); + } + + + /** + * + */ + protected Status getStatus () + { + Status result; + + File source = getSourceFile (); + + if (source == null) + { + this.status = Status.NOT_LOAD; + } + else if (this.sourceTime != source.lastModified ()) + { + this.status = Status.EXPIRED; + } + + result = this.status; + + // + return (result); + } + + + /** + * + */ + public void setUpdated () + { + File source = getSourceFile (); + + if (source == null) + { + this.status = Status.NOT_LOAD; + } + else + { + this.sourceTime = source.lastModified (); + this.status = Status.UPDATED; + } + } + + + /** + * + */ + public void setNotLoad () + { + this.status = Status.NOT_LOAD; + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/EtcGroupFile.java b/src/fr/devinsy/util/unix/EtcGroupFile.java new file mode 100644 index 0000000..7dae46c --- /dev/null +++ b/src/fr/devinsy/util/unix/EtcGroupFile.java @@ -0,0 +1,198 @@ +package fr.devinsy.util.unix; + + +import java.util.*; + + +/** + * + */ +public class EtcGroupFile extends CachedFile +{ + static private org.apache.log4j.Logger logger; + static + { + logger = org.apache.log4j.Logger.getLogger (EtcGroupFile.class); + } + + static EtcGroupFile instance; + static + { + instance = null; + } + + protected Groups groups; + + /** + * + */ + protected EtcGroupFile () + { + super ("/etc/group"); + this.groups = null; + } + + + /** + * + */ + static public EtcGroupFile instance () + { + EtcGroupFile result; + + if (EtcGroupFile.instance == null) + { + EtcGroupFile.instance = new EtcGroupFile (); + } + + result = EtcGroupFile.instance; + + // + return (result); + } + + + /** + * + */ + protected Groups updatedGroups () + { + Groups result; + + if (getStatus () != Status.UPDATED) + { + this.groups = EtcGroupFileReader.load (); + + if (this.groups == null) + { + setNotLoad (); + } + else + { + setUpdated (); + } + } + + result = this.groups; + + // + return (result); + } + + + /** + * + */ + public Group get (String name) + { + Group result; + + Groups groups = updatedGroups (); + + if (groups == null) + { + result = null; + } + else + { + result = groups.getByName (name); + } + + // + return (result); + } + + + /** + * + */ + public Group get (int gid) + { + Group result; + + Groups groups = updatedGroups (); + + if (groups == null) + { + result = null; + } + else + { + result = groups.getByGid (gid); + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (String name) + { + boolean result; + + Groups groups = updatedGroups (); + + if (groups == null) + { + result = false; + } + else + { + result = groups.contains (name); + } + + // + return (result); + } + + + /** + * + */ + public Vector getLoginGroups (String login) + { + Vector result; + + Groups groups = updatedGroups (); + + result = groups.getLoginGroups (login); + + // + return (result); + } + + /** + * + */ + public String getLoginGroupsString (String login) + { + String result; + + groups = updatedGroups (); + + result = groups.getLoginGroupsString (login); + + // + return (result); + } + + + + /** + * + */ + public String toString () + { + String result; + + result = this.groups.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/EtcGroupFileReader.java b/src/fr/devinsy/util/unix/EtcGroupFileReader.java new file mode 100644 index 0000000..4e3cd39 --- /dev/null +++ b/src/fr/devinsy/util/unix/EtcGroupFileReader.java @@ -0,0 +1,81 @@ +package fr.devinsy.util.unix; + +import java.io.*; + + + +/** + * + */ +public class EtcGroupFileReader +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (EtcGroupFileReader.class); + + + /** + * + */ + static public Groups load () + { + Groups result; + + BufferedReader file; + + try + { + file = new BufferedReader (new FileReader ("/etc/group")); + } + catch(FileNotFoundException exception) + { + logger.error ("File not found"); + file = null; + } + + if (file == null) + { + result = null; + } + else + { + result = new Groups (); + + try + { + String line; + while ((line = file.readLine ()) != null) + { + String[] tokens = line.split (":"); + + Group group = new Group (); + group.setName (tokens[0]); + group.setPassword (tokens[1]); + group.setGid ((new Integer (tokens[2])).intValue ()); + + // Manage the case of empty shell. + if (tokens.length == 4) + { + String[] tokensBis = tokens[3].split (","); + + for (int tokenCounter = 0; tokenCounter < tokensBis.length; tokenCounter++) + { + group.addMember (tokensBis[tokenCounter]); + } + } + result.add (group); + } + + file.close(); + } + catch (java.io.IOException exception) + { + logger.error ("Exception here."); + result = null; + } + } + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/EtcPasswdFile.java b/src/fr/devinsy/util/unix/EtcPasswdFile.java new file mode 100644 index 0000000..156eb59 --- /dev/null +++ b/src/fr/devinsy/util/unix/EtcPasswdFile.java @@ -0,0 +1,173 @@ +package fr.devinsy.util.unix; + + + +/** + * + */ +public class EtcPasswdFile extends CachedFile +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (EtcPasswdFile.class); + + static EtcPasswdFile instance = null; + protected Users users; + + + /** + * + */ + protected EtcPasswdFile () + { + super ("/etc/passwd"); + this.users = null; + } + + + /** + * + */ + static public EtcPasswdFile instance () + { + EtcPasswdFile result; + + if (EtcPasswdFile.instance == null) + { + EtcPasswdFile.instance = new EtcPasswdFile (); + } + + result = EtcPasswdFile.instance; + + // + return (result); + } + + + /** + * + */ + protected Users update () + { + Users result; + + logger.debug ("updating"); + this.users = EtcPasswdFileReader.load (); + + if (this.users == null) + { + setNotLoad (); + } + else + { + setUpdated (); + } + + result = this.users; + + // + return (result); + } + + + /** + * + */ + protected Users updatedUsers () + { + Users result; + + if (getStatus () != Status.UPDATED) + { + update(); + } + + result = this.users; + + // + return (result); + } + + + /** + * + */ + public User get (String login) + { + User result; + + Users users = updatedUsers (); + + if (users == null) + { + result = null; + } + else + { + result = users.getByLogin (login); + } + + // + return (result); + } + + + /** + * + */ + public User get (int uid) + { + User result; + + Users users = updatedUsers (); + + if (users == null) + { + result = null; + } + else + { + result = users.getByUid (uid); + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (String login) + { + boolean result; + + Users users = updatedUsers (); + + if (users == null) + { + result = false; + } + else + { + result = users.contains (login); + } + + // + return (result); + } + + + /** + * + */ + public String toString () + { + String result; + + result = this.users.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/EtcPasswdFileReader.java b/src/fr/devinsy/util/unix/EtcPasswdFileReader.java new file mode 100644 index 0000000..1e09f7d --- /dev/null +++ b/src/fr/devinsy/util/unix/EtcPasswdFileReader.java @@ -0,0 +1,84 @@ +package fr.devinsy.util.unix; + +import java.io.*; + + + +/** + * + */ +public class EtcPasswdFileReader +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (EtcPasswdFileReader.class); + + + /** + * + */ + static public Users load () + { + Users result; + + BufferedReader file; + + try + { + file = new BufferedReader (new FileReader ("/etc/passwd")); + } + catch(FileNotFoundException exception) + { + logger.error ("File not found"); + file = null; + } + + if (file == null) + { + result = null; + } + else + { + result = new Users (); + + try + { + String line; + while ((line = file.readLine ()) != null) + { + String[] tokens = line.split (":"); + + User user = new User (); + user.setLogin (tokens[0]); + user.setPassword (tokens[1]); + user.setUid ((new Integer (tokens[2])).intValue ()); + user.setGid ((new Integer (tokens[3])).intValue ()); + user.setRealName (tokens[4]); + user.setHomeDirectory (tokens[5]); + + // Manage the case of empty shell. + if (tokens.length == 7) + { + user.setShell (tokens[6]); + } + else + { + user.setShell (""); + } + + result.add (user); + } + + file.close(); + } + catch (java.io.IOException exception) + { + logger.error ("Exception here."); + result = null; + } + } + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/Group.java b/src/fr/devinsy/util/unix/Group.java new file mode 100644 index 0000000..5973730 --- /dev/null +++ b/src/fr/devinsy/util/unix/Group.java @@ -0,0 +1,215 @@ +package fr.devinsy.util.unix; + + +import java.util.*; + + +/** + * + */ +public class Group +{ + static private org.apache.log4j.Logger logger; + + static + { + logger = org.apache.log4j.Logger.getLogger (Group.class); + } + + /* + * /usr/include/grp.h + * + * The group structure. + * struct group + * { + * char *gr_name; Group name. + * char *gr_passwd; Password. + * __gid_t gr_gid; Group ID. + * char **gr_mem; Member list. + * }; + */ + + + protected String name; + protected String password; + protected int gid; + protected Vector members; + + + /** + * + */ + public Group () + { + this.name = null; + this.password = null; + this.gid = -1; + this.members = new Vector (); + } + + + + /** + * + */ + public void addMember (String login) + { + if ((login != null) && (login.length () != 0)) + { + this.members.add (login); + } + } + + /** + * + */ + public int getGid () + { + int result; + + result = this.gid; + + // + return (result); + } + + /** + * + */ + public int gid () + { + int result; + + result = this.gid; + + // + return (result); + } + + /** + * + */ + public Vector getMembers () + { + Vector result; + + result = this.members; + + // + return (result); + } + + + /** + * + */ + public Vector members () + { + Vector result; + + result = this.members; + + // + return (result); + } + + + /** + * + */ + public String getName () + { + String result; + + result = this.name; + + // + return (result); + } + + /** + * + */ + public String name () + { + String result; + + result = this.name; + + // + return (result); + } + + /** + * + */ + public String passwd () + { + String result; + + result = this.password; + + // + return (result); + } + + /** + * + */ + public String getPassword () + { + String result; + + result = this.password; + + // + return (result); + } + + /** + * + */ + public void setGid (int gid) + { + this.gid = gid; + } + + /** + * + */ + public void setName (String name) + { + this.name = name; + } + + /** + * + */ + public void setPasswd (String password) + { + this.password = password; + } + + /** + * + */ + public void setPassword (String password) + { + this.password = password; + } + + /** + * + */ + public String toString () + { + String result; + + result = "|" + this.name + "|" + this.password + "|" + this.gid + "|" + this.members + "|"; + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/Groups.java b/src/fr/devinsy/util/unix/Groups.java new file mode 100644 index 0000000..2b83bd2 --- /dev/null +++ b/src/fr/devinsy/util/unix/Groups.java @@ -0,0 +1,226 @@ +package fr.devinsy.util.unix; + + +import java.util.*; + + +/** + * + */ +public class Groups extends Vector +{ + + private static final long serialVersionUID = 5802487312198869603L; + static private org.apache.log4j.Logger logger; + + static + { + logger = org.apache.log4j.Logger.getLogger (Groups.class); + } + + + /** + * + */ + public Groups () + { + super (); + } + + + /** + * + */ + public Group getByName (String name) + { + Group result; + + if (name == null) + { + result = null; + } + else + { + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + Group group = iterator.next (); + if (group.getName ().equals (name)) + { + ended = true; + result = group; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return (result); + } + + + /** + * + */ + public Group getByGid (int gid) + { + Group result; + + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + Group group = iterator.next (); + if (group.getGid () == gid) + { + ended = true; + result = group; + } + } + else + { + ended = true; + result = null; + } + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (String name) + { + boolean result; + + if (getByName (name) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (int gid) + { + boolean result; + + if (getByGid (gid) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + /** + * + */ + public Vector getLoginGroups (String login) + { + Vector result; + + result = new Vector (); + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + Group group = iterator.next (); + + if (group.members ().contains (login)) + { + result.add (group.getName ()); + } + } + + // + return (result); + } + + + /** + * + */ + public String getLoginGroupsString (String login) + { + String result; + + Vector groups = getLoginGroups (login); + + StringBuffer string = new StringBuffer (); + + for (String group : groups) + { + if (string.length () == 0) + { + string.append (group); + } + else + { + string.append (","); + string.append (group); + } + } + + result = string.toString (); + + // + return (result); + } + + + /** + * + */ + public String toString () + { + String result; + + StringBuffer out; + out = new StringBuffer (); + + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + out.append (iterator.next ().toString () + "\n"); + } + + result = out.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/Unix.java b/src/fr/devinsy/util/unix/Unix.java new file mode 100644 index 0000000..9872da0 --- /dev/null +++ b/src/fr/devinsy/util/unix/Unix.java @@ -0,0 +1,607 @@ +package fr.devinsy.util.unix; + + +import java.io.File; +import java.util.Vector; + +import fr.devinsy.util.StringConcatenator; +import fr.devinsy.util.cmdexec.CmdExec; +import fr.devinsy.util.cmdexec.StreamGobbler; +import fr.devinsy.util.unix.acl.Acl; +import fr.devinsy.util.unix.acl.AclManager; + + + +/** + * + */ +public class Unix +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (Unix.class); + static public final String SUDO = "/usr/bin/sudo"; + + + /** + * + */ + static public boolean isLogin (String login) + { + boolean result; + + result = EtcPasswdFile.instance().contains(login); + + // + return (result); + } + + + /** + * + */ + static public boolean isGroup (String groupName) + { + boolean result; + + result = EtcGroupFile.instance().contains(groupName); + + // + return (result); + } + + + /** + * + */ + static public User searchLogin(String login) + { + User result; + + result = EtcPasswdFile.instance ().get (login); + + // + return (result); + } + + + /** + * + */ + static public Group searchGroup (String groupName) + { + Group result; + + result = EtcGroupFile.instance ().get(groupName); + + // + return (result); + } + + + /** + * + */ + static public Vector searchLoginGroups (String login) + { + Vector result; + + result = EtcGroupFile.instance ().getLoginGroups (login); + + // + return (result); + } + + + /** + * chfn [ -f full-name ] [ username ] + */ + static public void setRealName (String login, String newRealName) throws Exception + { + if ((login == null) || (login.length () == 0)) + { + throw new Exception ("Login parameter undefined."); + } + else if (newRealName == null) + { + throw new Exception ("New real name parameter undefined."); + } + else + { + try + { + logger.info ("Real name changing for user [" + login + "]."); + CmdExec.run (SUDO, "chfn", "-f", newRealName, login); + EtcPasswdFile.instance().update(); + logger.info ("Real name changed for user [" + login + "]."); + } + catch (Exception exception) + { + throw new Exception ("Error detected on setting of the new real name for [" + login + "].", exception); + } + } + } + + + /** + * + */ + static public void setPassword (String login, String newPassword) throws Exception + { + if ((login == null) || (login.length () == 0)) + { + throw new Exception ("Login parameter undefined."); + } + else if (newPassword == null) + { + throw new Exception ("New password parameter undefined."); + } + else + { + try + { + logger.info ("Password setting for [" + login + "]."); + CmdExec.run (SUDO, "bash", "-c", "echo \"" + newPassword + "\"| passwd " + login + " --stdin"); + logger.info ("Password set for [" + login + "]."); + } + catch (Exception exception) + { + throw new Exception ("Error detected on setting of the new password for [" + login + "].", exception); + } + } + } + + + /** + * + */ + static public void createUserAccount (String login) throws Exception + { + if ((login == null) || (login.length () == 0)) + { + throw new Exception ("Login parameter undefined."); + } + else + { + createUserAccount(login, login); + } + } + + + /** + * + */ + static public void createUserAccount (String login, String name) throws Exception + { + if ((login == null) || (login.length () == 0)) + { + throw new Exception ("Login parameter undefined."); + } + else if ((name == null) || (name.length () == 0)) + { + throw new Exception ("Name parameter undefined."); + } + else + { + createUserAccount(login, name, "/home/" + login); + } + } + + + /** + * + */ + static public void createUserAccount (String login, String name, String home) throws Exception + { + if ((login == null) || (login.length () == 0)) + { + throw new Exception ("Login parameter undefined."); + } + else if ((name == null) || (name.length () == 0)) + { + throw new Exception ("Name parameter undefined."); + } + else if ((home == null) || (home.length () == 0)) + { + throw new Exception ("Home parameter undefined."); + } + else + { + try + { + logger.info ("Creating user account for [" + login + "]."); + CmdExec.run (SUDO, "/usr/sbin/useradd", "-c", name, "-d", home, login); + EtcPasswdFile.instance().update(); + logger.info ("User account created for [" + login + "]."); + } + catch(Exception exception) + { + throw new Exception ("Error detected creating user account [" + login + "].", exception); + } + } + } + + + /** + * + */ + static public void createUserAccount (String login, String name, String home, String password) throws Exception + { + if ((password == null) || (password.length () == 0)) + { + throw new Exception ("Password parameter undefined."); + } + else if (Unix.isLogin(login)) + { + throw new Exception ("Login [" + login + "] already in use"); + } + else + { + createUserAccount(login, name, home); + setPassword(login, password); + } + } + + + /** + * + */ + static public void deleteUserAccount (String login) throws Exception + { + if ((login == null) || (login.length() == 0)) + { + throw new Exception ("Login parameter undefined."); + } + else + { + try + { + logger.info ("Deleting user account for [" + login + "]."); + CmdExec.run (SUDO + " /usr/sbin/userdel " + login); + logger.info ("User account delted for [" + login + "]."); + } + catch (Exception exception) + { + throw new Exception ("Error running userdel command for login [" + login + "].", exception); + } + } + } + + + /** + * + */ + static public void deleteGroup (String group) throws Exception + { + if ((group == null) || (group.length() == 0)) + { + throw new Exception ("Group parameter undefined."); + } + else + { + try + { + logger.info ("Deleting group for [" + group + "]."); + CmdExec.run (SUDO + " groupdel " + group); + logger.info ("Group deleted for [" + group + "]."); + } + catch (Exception exception) + { + throw new Exception ("Error running groupdel command for group [" + group + "].", exception); + } + } + } + + + /** + * + */ + static public void modifyLogin (String sourceLogin, String targetLogin, String sourceHomeDirectory) throws Exception + { + logger.info ("Starting login modifying: [" + sourceLogin + "] -> [" + targetLogin + "]"); + if ((sourceLogin == null) || (sourceLogin.length () == 0)) + { + throw new Exception ("Original login parameters undefined"); + } + else if ((targetLogin == null) || (targetLogin.length () == 0)) + { + throw new Exception ("New login parameters undefined"); + } + else if (!Unix.isLogin(sourceLogin)) + { + throw new Exception ("Original login unknow: [" + sourceLogin + "]."); + } + else if (Unix.isLogin(targetLogin)) + { + throw new Exception ("New login unknow: [" + targetLogin + "]."); + } + else if (sourceHomeDirectory == null) + { + throw new Exception ("sourceHomeDirectory parameter undefined, thus no home directory move."); + } + else if (!new File(sourceHomeDirectory).exists()) + { + throw new Exception("Source home directory does not exist: [" + sourceHomeDirectory + "]."); + } + else + { + String targetHomeDirectory = new File(sourceHomeDirectory).getParent().toString() + "/" + targetLogin; + if (new File(targetHomeDirectory).exists()) + { + throw new Exception("Target home directory already exists: [" + targetHomeDirectory + "]."); + } + else + { + try + { + logger.info ("Login modifying: [" + sourceLogin + "] -> [" + targetLogin + "]"); + CmdExec.run (SUDO + " usermod -l "+ targetLogin + " " + sourceLogin); + logger.info ("Login modified: [" + sourceLogin + "] -> [" + targetLogin + "]"); + } + catch (Exception exception) + { + throw new Exception ("Login modification failed for [" + sourceLogin + "].", exception); + } + + try + { + logger.info ("Renaming home directory: [" + sourceHomeDirectory + "] -> [" + targetLogin + "]"); + CmdExec.run (SUDO + " mv " + sourceHomeDirectory + " " + targetHomeDirectory); + logger.info ("Home directory renamed: [" + sourceHomeDirectory + "] -> [" + targetLogin + "]"); + } + catch (Exception exception) + { + throw new Exception ("Home directory rename failed for [" + sourceHomeDirectory + "].", exception); + } + } + } + logger.info ("Login modifying done: [" + sourceLogin + "] -> [" + targetLogin + "]"); + } + + + /** + * + */ + static public void renameGroup (String sourceGroup, String targetGroup) throws Exception + { + logger.info ("Starting group renaming: [" + sourceGroup + "] -> [" + targetGroup + "]"); + if ((sourceGroup == null) || (sourceGroup.length () == 0)) + { + throw new Exception ("Original group name parameters undefined"); + } + else if ((targetGroup == null) || (targetGroup.length () == 0)) + { + throw new Exception ("New group name parameters undefined"); + } + else if (!Unix.isGroup(sourceGroup)) + { + throw new Exception ("Original group unknow: [" + sourceGroup + "]."); + } + else if (Unix.isGroup(targetGroup)) + { + throw new Exception ("New group unknow: [" + targetGroup + "]."); + } + else + { + try + { + logger.info ("Login modifying: [" + sourceGroup + "] -> [" + targetGroup + "]"); + CmdExec.run (SUDO + " groupmod -n "+ targetGroup + " " + sourceGroup); + logger.info ("Login modified: [" + sourceGroup + "] -> [" + targetGroup + "]"); + } + catch (Exception exception) + { + throw new Exception ("Group renaming failed for [" + sourceGroup + "].", exception); + } + } + logger.info ("Group renaming done: [" + sourceGroup + "] -> [" + targetGroup + "]"); + } + + + /** + * + */ + static public void recursiveChmod (String changes, String path) throws Exception + { + if ((changes == null) || (changes.length() == 0) || + (path == null) || (path.length() == 0)) + { + throw new Exception ("Parameter undefined: [" + changes + "][" + path + "]."); + } + else if (!new File(path).exists()) + { + throw new Exception ("Path not found: [" + path + "]."); + } + else + { + try + { + CmdExec.run (SUDO, "chmod", "-R", changes, path); + } + catch (Exception exception) + { + throw new Exception ("Error running recursive chmod command for [" + changes + "][" + path + "].", exception); + } + } + } + + /** + * + */ + static public void chmod (String changes, String path) throws Exception + { + if ((changes == null) || (changes.length() == 0) || + (path == null) || (path.length() == 0)) + { + throw new Exception ("Parameter undefined: [" + changes + "][" + path + "]."); + } + else if (!new File(path).exists()) + { + throw new Exception ("Path not found: [" + path + "]."); + } + else + { + try + { + CmdExec.run (SUDO, "chmod", changes, path); + } + catch (Exception exception) + { + throw new Exception ("Error running chmod command for [" + changes + "][" + path + "].", exception); + } + } + } + + + /** + * + */ + static public void setfacl (String ... args) throws Exception + { + try + { + CmdExec.run(SUDO, "setfacl", args, 1, 6); + } + catch (Exception exception) + { + throw new Exception ("Error running setfacl command for " + StringConcatenator.toStringWithBrackets(args) + ":" + exception.getMessage() + ".", exception); + } + } + + + /** + * + */ + static public String getAclData (String filePathName) throws Exception + { + String result; + + result = AclManager.getAclData(filePathName); + + // + return(result); + } + + + /** + * + */ + static public String[] getAclUsers (String filePathName) throws Exception + { + String[] result; + + Acl acl = AclManager.getAcl(filePathName); + + result = acl.currentAcl().getUserIds(); + + // + return(result); + } + + + /** + * + */ + static public void appendToFile (String text, String path) throws Exception + { + if ((text == null) || (text.length() == 0) || + (path == null) || (path.length() == 0)) + { + throw new Exception ("Parameter undefined: [" + text + "][" + path + "]."); + } + else + { + try + { + CmdExec.run (SUDO, "bash", "-c", "echo \"" + text + "\" >> " + path); + } + catch (Exception exception) + { + throw new Exception ("Error detected appending text to file [" + path + "].", exception); + } + } + } + + + /** + * + */ + static public void link (String sourcePath, String targetPath) throws Exception + { + logger.info("[" + sourcePath + "][" + targetPath + "]"); + if ((sourcePath == null) || (sourcePath.length() == 0) || + (targetPath == null) || (targetPath.length() == 0)) + { + throw new Exception ("Parameter undefined: [" + sourcePath + "][" + targetPath + "]."); + } + else + { + File sourceFile = new File (sourcePath); + File targetFile = new File (targetPath); + + if (!sourceFile.exists()) + { + throw new Exception ("Source does not exist: [" + sourcePath + "]."); + } + else if ((targetFile.exists()) && (!targetFile.isDirectory())) + { + throw new Exception ("Target already exists: [" + targetPath + "]."); + } + else + { + try + { + CmdExec.run (SUDO, "ln", "-s", sourcePath, targetPath); + } + catch (Exception exception) + { + throw new Exception ("Error detected linking [" + sourcePath + "][" + targetPath + "].", exception); + } + } + } + } + + + /** + * + */ + static public void unlink (String filePathName) throws Exception + { + logger.info("[" + filePathName + "]"); + if (filePathName == null) + { + throw new Exception ("Parameter undefined: [" + filePathName + "]."); + } + else + { + new File(filePathName).delete(); + } + } + + + /** + * + */ + static public void clearAclUser (String login, String filePathName) throws Exception + { + AclManager.clearUser(login, filePathName); + } + + + /** + * + */ + static public void clearAclGroup (String group, String filePathName) throws Exception + { + AclManager.clearGroup(group, filePathName); + } + + + /** + * + */ + static public void clearAcl (String id, String filePathName) throws Exception + { + AclManager.clearId(id, filePathName); + } +} + + // //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/User.java b/src/fr/devinsy/util/unix/User.java new file mode 100644 index 0000000..a8fd43d --- /dev/null +++ b/src/fr/devinsy/util/unix/User.java @@ -0,0 +1,346 @@ +package fr.devinsy.util.unix; + + + + +/** + * + */ +public class User +{ + static private org.apache.log4j.Logger logger; + + static + { + logger = org.apache.log4j.Logger.getLogger (User.class); + } + + /* + * /usr/include/pwd.h + * + * The passwd structure. + * struct passwd + * { + * char *pw_name;D Username. + * char *pw_passwd; Password. + * __uid_t pw_uid; User ID. + * __gid_t pw_gid; Group ID. + * char *pw_gecos; Real name. + * char *pw_dir; Home directory. + * char *pw_shell; Shell program. + * }; + */ + + protected String login; + protected String password; + protected int uid; + protected int gid; + protected String realName; + protected String homeDirectory; + protected String shell; + + + /** + * + */ + public User () + { + this.login = null; + this.password = null; + this.uid = -1; + this.gid = -1; + this.realName = null; + this.homeDirectory = null; + this.shell = null; + } + + + /** + * + */ + public User (User user) + { + this.login = user.login(); + this.password = user.passwd(); + this.uid = user.uid(); + this.gid = user.gid(); + this.realName = user.realName(); + this.homeDirectory = user.homeDirectory(); + this.shell = user.shell(); + } + + + /** + * + */ + public int getGid () + { + int result; + + result = this.gid; + + // + return (result); + } + + /** + * + */ + public int gid () + { + int result; + + result = this.gid; + + // + return (result); + } + + /** + * + */ + public String getHomeDirectory () + { + String result; + + result = this.homeDirectory; + + // + return (result); + } + + /** + * + */ + public String homeDirectory () + { + String result; + + result = this.homeDirectory; + + // + return (result); + } + + /** + * + */ + public String getLogin () + { + String result; + + result = this.login; + + // + return (result); + } + + /** + * + */ + public String login () + { + String result; + + result = this.login; + + // + return (result); + } + + /** + * + */ + public String getPasswd () + { + String result; + + result = this.password; + + // + return (result); + } + + /** + * + */ + public String passwd () + { + String result; + + result = this.password; + + // + return (result); + } + + /** + * + */ + public String getPassword () + { + String result; + + result = this.password; + + // + return (result); + } + + /** + * + */ + public String getRealName () + { + String result; + + result = this.realName; + + // + return (result); + } + + /** + * + */ + public String realName () + { + String result; + + result = this.realName; + + // + return (result); + } + + /** + * + */ + public String getShell () + { + String result; + + result = this.shell; + + // + return (result); + } + + /** + * + */ + public String shell () + { + String result; + + result = this.shell; + + // + return (result); + } + + /** + * + */ + public int getUid () + { + int result; + + result = this.uid; + + // + return (result); + } + + /** + * + */ + public int uid () + { + int result; + + result = this.uid; + + // + return (result); + } + + /** + * + */ + public void setHomeDirectory (String homeDirectory) + { + this.homeDirectory = homeDirectory; + } + + /** + * + */ + public void setGid (int gid) + { + this.gid = gid; + } + + /** + * + */ + public void setLogin (String login) + { + this.login = login; + } + + /** + * + */ + public void setPasswd (String password) + { + this.password = password; + } + + /** + * + */ + public void setPassword (String password) + { + this.password = password; + } + + /** + * + */ + public void setRealName (String realName) + { + this.realName = realName; + } + + /** + * + */ + public void setShell (String shell) + { + this.shell = shell; + } + + /** + * + */ + public void setUid (int uid) + { + this.uid = uid; + } + + /** + * + */ + public String toString () + { + String result; + + result = "|" + this.login + "|" + this.password + "|" + this.uid + "|" + this.gid + "|" + this.realName + "|" + this.homeDirectory + "|" + this.shell + "|"; + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/Users.java b/src/fr/devinsy/util/unix/Users.java new file mode 100644 index 0000000..4af0c37 --- /dev/null +++ b/src/fr/devinsy/util/unix/Users.java @@ -0,0 +1,172 @@ +package fr.devinsy.util.unix; + + +import java.util.*; + + +/** + * + */ +public class Users extends Vector +{ + private static final long serialVersionUID = -7178304512851592399L; + static private org.apache.log4j.Logger logger; + + static + { + logger = org.apache.log4j.Logger.getLogger (Users.class); + } + + + /** + * + */ + public Users () + { + super (); + } + + + /** + * + */ + public User getByLogin (String login) + { + User result; + + if (login == null) + { + result = null; + } + else + { + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + User user = iterator.next (); + if (user.getLogin ().equals (login)) + { + ended = true; + result = user; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return (result); + } + + + /** + * + */ + public User getByUid (int uid) + { + User result; + + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + User user = iterator.next (); + if (user.getUid () == uid) + { + ended = true; + result = user; + } + } + else + { + ended = true; + result = null; + } + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (String login) + { + boolean result; + + if (getByLogin (login) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (int uid) + { + boolean result; + + if (getByUid (uid) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + + + + /** + * + */ + public String toString () + { + String result; + + StringBuffer out; + out = new StringBuffer (); + + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + out.append (iterator.next ().toString () + "\n"); + } + + result = out.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/acl/Acl.java b/src/fr/devinsy/util/unix/acl/Acl.java new file mode 100644 index 0000000..e6e5b31 --- /dev/null +++ b/src/fr/devinsy/util/unix/acl/Acl.java @@ -0,0 +1,211 @@ +package fr.devinsy.util.unix.acl; + + +/** + * + */ +public class Acl +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (Acl.class); + + + /* + # file: goo39 + # owner: goo39 + # group: goo39 + user::rwx + user:cpm:rwx #effective:rwx + user:goo39:rwx #effective:rwx + group::--- #effective:--- + group:goo40:rwx #effective:rwx + mask::rwx + other::--- + default:user::rwx + default:user:cpm:rwx #effective:rwx + default:group::--- #effective:--- + default:group:cpm:rwx #effective:rwx + default:group:goo40:rwx #effective:rwx + default:mask::rwx + default:other::--- + */ + + protected String filePathname; + protected String owner; + protected String group; + + protected AclEntries currentAcl; + protected AclEntries defaultAcl; + + /** + * + */ + public Acl (String filePathname) + { + this.filePathname = filePathname; + this.owner = ""; + this.group = ""; + this.currentAcl = new AclEntries(); + this.defaultAcl = new AclEntries(); + } + + + /** + * + */ + public String filePathname() + { + String result; + + result = this.filePathname; + + // + return(result); + } + + + /** + * + */ + public String owner() + { + String result; + + result = this.owner; + + // + return(result); + } + + + /** + * + */ + public void setOwner(String owner) + { + this.owner = owner; + } + + + /** + * + */ + public String group() + { + String result; + + result = this.group; + + // + return(result); + } + + + /** + * + */ + public void setGroup(String group) + { + this.group = group; + } + + + /** + * + */ + public AclEntries currentAcl() + { + AclEntries result; + + result = this.currentAcl; + + // + return(result); + } + + + /** + * + */ + public AclEntries defaultAcl() + { + AclEntries result; + + result = this.defaultAcl; + + // + return(result); + } + + + /** + * + */ + public boolean containsUser(String login) + { + boolean result; + + result = contains(AclEntry.Type.USER, login); + + // + return(result); + } + + + /** + * + */ + public boolean containsGroup(String group) + { + boolean result; + + result = contains(AclEntry.Type.GROUP, group); + + // + return(result); + } + + + /** + * + */ + public boolean containsId(String id) + { + boolean result; + + if ((containsUser(id) || containsGroup(id))) + { + result = true; + } + else + { + result = false; + } + + // + return(result); + } + + + /** + * + */ + public boolean contains(AclEntry.Type type, String id) + { + boolean result; + + if ((this.currentAcl().contains(type, id)) || + (this.defaultAcl().contains(type, id))) + { + result = true; + } + else + { + result = false; + } + + // + return(result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/acl/AclEntries.java b/src/fr/devinsy/util/unix/acl/AclEntries.java new file mode 100644 index 0000000..dad87d7 --- /dev/null +++ b/src/fr/devinsy/util/unix/acl/AclEntries.java @@ -0,0 +1,203 @@ +package fr.devinsy.util.unix.acl; + + +import java.util.Iterator; +import java.util.Vector; + + +/** + * + */ +public class AclEntries extends Vector +{ + private static final long serialVersionUID = 5802487312198869603L; + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (AclEntries.class); + + /** + * + */ + public AclEntries () + { + super (); + } + + + /** + * + */ + public AclEntry get (AclEntry.Type type, String id) + { + AclEntry result; + + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + AclEntry entry = iterator.next (); + if ((type == entry.type()) && (entry.id ().equals(id))) + { + ended = true; + result = entry; + } + } + else + { + ended = true; + result = null; + } + } + + // + return (result); + } + + + /* + * + */ + public boolean contains(AclEntry.Type type, String id) + { + boolean result; + + if (this.get (type, id) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + /** + * + */ + public String[] getUserIds () + { + String[] result; + + // + Vector ids = new Vector (); + + for (AclEntry entry : this) + { + if ((entry.type == AclEntry.Type.USER) && (!ids.contains(entry.id()))) + { + ids.add(entry.id()); + } + } + + // + result = new String[ids.size()]; + + for (int nId = 0; nId < ids.size(); nId++) + { + result[nId] = ids.get(nId); + } + + // + return (result); + } + + + /** + * + */ + public String[] getGroupIds () + { + String[] result; + + Vector ids = new Vector (); + + for (AclEntry entry : this) + { + if ((entry.type == AclEntry.Type.GROUP) && (!ids.contains(entry.id()))) + { + ids.add(entry.id()); + } + } + + result = (String[]) ids.toArray(); + + // + return (result); + } + + + /** + * + */ + public String[] getIds () + { + String[] result; + + Vector ids = new Vector (); + + for (AclEntry entry : this) + { + if (!ids.contains(entry.id())) + { + ids.add(entry.id()); + } + } + + result = (String[]) ids.toArray(); + + // + return (result); + } + + + /** + * + */ + public boolean containsId(String id) + { + boolean result; + + if ((this.get(AclEntry.Type.USER, id) == null) && + (this.get(AclEntry.Type.GROUP, id) == null)) + { + result = false; + } + else + { + result = true; + } + + // + return(result); + } + + /** + * + */ + public String toString () + { + String result; + + StringBuffer out; + out = new StringBuffer (); + + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + out.append (iterator.next ().toString () + "\n"); + } + + result = out.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/acl/AclEntry.java b/src/fr/devinsy/util/unix/acl/AclEntry.java new file mode 100644 index 0000000..9c1abbd --- /dev/null +++ b/src/fr/devinsy/util/unix/acl/AclEntry.java @@ -0,0 +1,97 @@ +package fr.devinsy.util.unix.acl; + + +/** + * + */ +public class AclEntry +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (AclEntry.class); + + + /* + user::rwx + user:cpm:rwx #effective:rwx + user:goo39:rwx #effective:rwx + group::--- #effective:--- + group:goo40:rwx #effective:rwx + mask::rwx + other::--- + */ + + public enum Type {NONE, USER, GROUP, MASK, OTHER}; + + + protected Type type; + protected String id; + protected String permission; + + + /** + * + */ + public AclEntry (Type type, String id, String permission) + { + this.type = type; + this.id = id; + this.permission = permission; + } + + + /** + * + */ + public Type type() + { + Type result; + + result = this.type; + + // + return(result); + } + + + /** + * + */ + public String id() + { + String result; + + result = this.id; + + // + return(result); + } + + + /** + * + */ + public String permission() + { + String result; + + result = this.type.toString() + ":" + this.id + ":" + this.permission; + + // + return(result); + } + + + /** + * + */ + public String toString() + { + String result; + + result = permission; + + // + return(result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/unix/acl/AclManager.java b/src/fr/devinsy/util/unix/acl/AclManager.java new file mode 100644 index 0000000..e757bf0 --- /dev/null +++ b/src/fr/devinsy/util/unix/acl/AclManager.java @@ -0,0 +1,426 @@ +package fr.devinsy.util.unix.acl; + + +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import fr.devinsy.util.StringConcatenator; +import fr.devinsy.util.cmdexec.CmdExec; +import fr.devinsy.util.unix.Unix; + + + +/** + * + */ +public class AclManager +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (AclManager.class); + static public final String SUDO = "/usr/bin/sudo"; + + static final public Pattern USER_PATTERN = Pattern.compile("^user:(.*):(.*)$"); + static final public Pattern GROUP_PATTERN = Pattern.compile("^group:(.*):(.*)$"); + static final public Pattern MASK_PATTERN = Pattern.compile("^mask:(.*):(.*)$"); + static final public Pattern OTHER_PATTERN = Pattern.compile("^other:(.*):(.*)$"); + static final public Pattern DEFAULT_USER_PATTERN = Pattern.compile("^default:user:(.*):(.*)$"); + static final public Pattern DEFAULT_GROUP_PATTERN = Pattern.compile("^default:group:(.*):(.*)$"); + static final public Pattern DEFAULT_MASK_PATTERN = Pattern.compile("^default:mask:(.*):(.*)$"); + static final public Pattern DEFAULT_OTHER_PATTERN = Pattern.compile("^default:other:(.*):(.*)$"); + + + /** + * + */ + static public void setfacl (String ... args) throws Exception + { + try + { + CmdExec.run(SUDO, "setfacl", args, 1, 5); + } + catch (Exception exception) + { + throw new Exception ("Error running setfacl command for " + StringConcatenator.toStringWithBrackets(args) + ":" + exception.getMessage() + "."); + } + } + + + /** + * + */ + static public String getAclData (String filePathName) throws Exception + { + String result; + + try + { + logger.info ("Getting Acl data for [" + filePathName + "]."); + result = CmdExec.run (SUDO, "/usr/bin/getfacl", "--no-effective", filePathName); + logger.info ("Acl data got for [" + filePathName + "]."); + } + catch (Exception exception) + { + throw new Exception ("Error getting ACL for [" + filePathName + "].", exception); + } + + // + return(result); + } + + + /** + * + */ + static public String[] getAclEntryLines (String filePathName) + { + String[] result; + + try + { + result = getAclData(filePathName).split("\n"); + } + catch (Exception exception) + { + result = new String[0]; + } + + // + return (result); + } + + + /** + * + */ + static public Acl getAcl (String filePathName) throws Exception + { + Acl result; + + result = new Acl(filePathName); + + String[] entries = getAclEntryLines(filePathName); + + // Login pattern: "^[a-z_][a-z0-9_-]*$". + logger.debug("Line=[" + entries[1] + "]"); + Matcher matcher = Pattern.compile("^#\\sowner:\\s([a-z_][a-z0-9_-]*)$").matcher(entries[1]); + if (matcher.matches()) + { + logger.debug("group=[" + matcher.group(1) + "]"); + result.setOwner(matcher.group(1)); + } + + // Group pattern: "^[a-z_][a-z0-9_-]*$". + logger.debug("Line=[" + entries[2] + "]"); + matcher = Pattern.compile("^#\\sgroup:\\s([a-z_][a-z0-9_-]*)$").matcher(entries[2]); + if (matcher.matches()) + { + logger.debug("group=[" + matcher.group(1) + "]"); + result.setOwner(matcher.group(1)); + } + + + for (int nEntry = 3; nEntry < entries.length; nEntry++) + { + String entryLine = entries[nEntry]; + logger.debug("Line=[" + entryLine + "]"); + + // + Matcher userMatcher = USER_PATTERN.matcher(entryLine); + Matcher groupMatcher = GROUP_PATTERN.matcher(entryLine); + Matcher maskMatcher = MASK_PATTERN.matcher(entryLine); + Matcher otherMatcher = OTHER_PATTERN.matcher(entryLine); + Matcher defaultUserMatcher = DEFAULT_USER_PATTERN.matcher(entryLine); + Matcher defaultGroupMatcher = DEFAULT_GROUP_PATTERN.matcher(entryLine); + Matcher defaultMaskMatcher = DEFAULT_MASK_PATTERN.matcher(entryLine); + Matcher defaultOtherMatcher = DEFAULT_OTHER_PATTERN.matcher(entryLine); + + AclEntry entry; + if (userMatcher.matches()) + { + entry = new AclEntry(AclEntry.Type.USER, userMatcher.group(1), userMatcher.group(2)); + result.currentAcl().add(entry); + } + else if (groupMatcher.matches()) + { + entry = new AclEntry(AclEntry.Type.GROUP, groupMatcher.group(1), groupMatcher.group(2)); + result.currentAcl().add(entry); + } + else if (maskMatcher.matches()) + { + entry = new AclEntry(AclEntry.Type.MASK, maskMatcher.group(1), maskMatcher.group(2)); + result.currentAcl().add(entry); + } + else if (otherMatcher.matches()) + { + entry = new AclEntry(AclEntry.Type.OTHER, otherMatcher.group(1), otherMatcher.group(2)); + result.currentAcl().add(entry); + } + else if (defaultUserMatcher.matches()) + { + entry = new AclEntry(AclEntry.Type.USER, defaultUserMatcher.group(1), defaultUserMatcher.group(2)); + result.defaultAcl().add(entry); + } + else if (defaultGroupMatcher.matches()) + { + entry = new AclEntry(AclEntry.Type.GROUP, defaultGroupMatcher.group(1), defaultGroupMatcher.group(2)); + result.defaultAcl().add(entry); + } + else if (defaultMaskMatcher.matches()) + { + entry = new AclEntry(AclEntry.Type.MASK, defaultMaskMatcher.group(1), defaultMaskMatcher.group(2)); + result.defaultAcl().add(entry); + } + else if (defaultOtherMatcher.matches()) + { + entry = new AclEntry(AclEntry.Type.OTHER, defaultOtherMatcher.group(1), defaultOtherMatcher.group(2)); + result.defaultAcl().add(entry); + } + else + { + throw new Exception ("Unknow ACL entry line pattern for [" + entryLine + "]."); + } + + logger.debug("Acl entry decoded: [" + entry.toString() + "]"); + } + + // + return (result); + } + + + /** + * + */ + public static boolean isUsed(AclEntry.Type type, String id, String filePath, String[] filePathNames, int depth) throws Exception + { + boolean result; + + result = false; + boolean ended = false; + int nLine = 0; + while (!ended) + { + if (nLine < filePathNames.length) + { + String filePathName = filePathNames[nLine]; + if (isUsed(type, id, filePath + "/" + filePathName, depth)) + { + ended = true; + result = true; + } + else + { + nLine += 1; + } + } + else + { + ended = true; + result = false; + } + } + + // + return(result); + } + + + /** + * + */ + public static boolean isUsed(AclEntry.Type type, String id, String filePathName, int depth) throws Exception + { + boolean result; + + if ((type == null) || + (id == null) || (id.length() == 0) || + (filePathName == null) || (filePathName.length() == 0) || + (depth < 0)) + { + throw new Exception("Bad parameter: [" + type + "][" + id + "][" + filePathName + "][" + depth + "]."); + } + else + { + File file = new File (filePathName); + if (!file.exists()) + { + throw new Exception ("File does not exist [" + filePathName + "]."); + } + else + { + Acl acl = getAcl(filePathName); + if (acl.contains(type, id)) + { + result = true; + } + else if ((file.isDirectory()) && (depth > 0)) + { + result = isUsed(type, id, filePathName, file.list(), depth - 1); + } + else + { + result = false; + } + } + } + + // + return (result); + } + + + /** + * + */ + public static boolean isUsed(AclEntry.Type type, String id, String filePathName) throws Exception + { + boolean result; + + result = isUsed(type, id, filePathName, 0); + + // + return (result); + } + + + /** + * + */ + public static boolean isUsed(String id, String[] filePathNames, int depth) throws Exception + { + boolean result; + + result = false; + boolean ended = false; + int nLine = 0; + while (!ended) + { + if (nLine < filePathNames.length) + { + String filePathName = filePathNames[nLine]; + if (isUsed(id, filePathName, depth)) + { + ended = true; + result = true; + } + else + { + nLine += 1; + } + } + else + { + ended = true; + result = false; + } + } + + // + return(result); + } + + + /** + * + */ + public static boolean isUsed(String id, String filePathName, int depth) throws Exception + { + boolean result; + + if ((id == null) || (id.length() == 0) || + (filePathName == null) || (filePathName.length() == 0) || + (depth < 0)) + { + throw new Exception("Bad parameter: [" + id + "][" + filePathName + "][" + depth + "]."); + } + else + { + File file = new File (filePathName); + if (!file.exists()) + { + throw new Exception ("File does not exist [" + filePathName + "]."); + } + else + { + Acl acl = getAcl(filePathName); + if (acl.containsId(id)) + { + result = true; + } + else if ((file.isDirectory()) && (depth > 0)) + { + result = isUsed(id, file.list(), depth - 1); + } + else + { + result = false; + } + } + } + + // + return (result); + } + + + /** + * + */ + public static boolean isUsed(String id, String filePathName) throws Exception + { + boolean result; + + result = isUsed(id, filePathName, 0); + + // + return (result); + } + + + /** + * + */ + public static void clearUser(String login, String filePathName) throws Exception + { + if ((login == null) || (login.length() == 0) || + (filePathName == null) || (filePathName.length() == 0)) + { + throw new Exception("Bad parameters [" + login + "][" + filePathName + "]."); + } + else + { + Unix.setfacl("-R", "-L", "-x", "user:" + login, filePathName); + Unix.setfacl("-R", "-L", "-d", "-x", "user:" + login, filePathName); + } + } + + + /** + * + */ + public static void clearGroup(String group, String filePathName) throws Exception + { + if ((group == null) || (group.length() == 0) || + (filePathName == null) || (filePathName.length() == 0)) + { + throw new Exception("Bad parameters [" + group + "][" + filePathName + "]."); + } + else + { + Unix.setfacl("-R", "-L", "-x", "group:" + group, filePathName); + Unix.setfacl("-R", "-L", "-d", "-x", "group:" + group, filePathName); + } + } + + + /** + * + */ + public static void clearId(String id, String filePathName) throws Exception + { + clearUser(id, filePathName); + clearGroup(id, filePathName); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/web/FileItemHelper.java b/src/fr/devinsy/util/web/FileItemHelper.java new file mode 100644 index 0000000..7214ad9 --- /dev/null +++ b/src/fr/devinsy/util/web/FileItemHelper.java @@ -0,0 +1,85 @@ +package fr.devinsy.util.web; + +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.fileupload.FileItem; + + +/** + * + */ +public class FileItemHelper +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (FileItemHelper.class); + + /** + * List FileItem + */ + static public String getItemValue (List items, String name) + { + String result; + + FileItem item = getItem(items, name); + + if (item == null) + { + result = null; + } + else + { + result = item.getString(); + } + + // + return(result); + } + + + /** + * List FileItem + */ + static public FileItem getItem (List items, String name) + { + FileItem result; + + if (name == null) + { + result = null; + } + else + { + result = null; + boolean ended = false; + int itemIndex = 0; + while (!ended) + { + if (itemIndex < items.size()) + { + FileItem item = (FileItem) items.get(itemIndex); + + if (name.equals(item.getFieldName())) + { + ended = true; + result = item; + } + else + { + itemIndex += 1; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return(result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/web/Redirector.java b/src/fr/devinsy/util/web/Redirector.java new file mode 100644 index 0000000..2d10f70 --- /dev/null +++ b/src/fr/devinsy/util/web/Redirector.java @@ -0,0 +1,26 @@ +package fr.devinsy.util.web; + +import javax.servlet.http.HttpServletResponse; + + + +/** + * + */ +public class Redirector +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (Redirector.class); + + /** + * + */ + static public void redirect (HttpServletResponse response, String destination) + { + logger.info ("Redirect to <" + destination + ">"); + + response.setHeader ("Location", destination); + response.setStatus (HttpServletResponse.SC_MOVED_TEMPORARILY); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/web/SimpleSecurityAgent.java b/src/fr/devinsy/util/web/SimpleSecurityAgent.java new file mode 100644 index 0000000..898035a --- /dev/null +++ b/src/fr/devinsy/util/web/SimpleSecurityAgent.java @@ -0,0 +1,250 @@ +package fr.devinsy.util.web; + + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import javax.servlet.http.*; +import sun.security.provider.MD5; + + +/** + * + */ +public class SimpleSecurityAgent +{ + static protected org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (SimpleSecurityAgent.class); + final static public String USERID_LABEL = "securityAgent.userId"; + final static public String ACCOUNTID_LABEL = "securityAgent.accountId"; + final static public String AUTH_LABEL = "securityAgent.auth"; + protected String userIdLabel; + protected String accountIdLabel; + protected String authLabel; + protected String secretKey; + + + + /** + * + */ + public SimpleSecurityAgent(String prefix, String secretKey) + { + this.userIdLabel = prefix + "." + USERID_LABEL; + this.accountIdLabel = prefix + "." + ACCOUNTID_LABEL; + this.authLabel= prefix + "." + AUTH_LABEL; + this.secretKey = secretKey; + } + + + /** + * + */ + static String md5sum(String source) + { + String result; + + result = org.apache.commons.codec.digest.DigestUtils.md5Hex(source); + + + // + return(result); + } + + + /** + * + */ + static public Cookie buildCookie (String name, String value, int duration) + { + Cookie result; + + result = new Cookie (name, value); + result.setMaxAge (duration); + result.setPath ("/"); + result.setSecure (false); + + // + return (result); + } + + + /** + * + */ + static public Cookie getCookie (Cookie[] cookies, String key) + { + Cookie result = null; + + if (cookies == null) + { + result = null; + } + else + { + boolean ended = false; + int cookieCounter = 0; + while (!ended) + { + if (cookieCounter < cookies.length) + { + if (key.equals (cookies[cookieCounter].getName ())) + { + ended = true; + result = cookies[cookieCounter]; + } + else + { + cookieCounter += 1; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return (result); + } + + + /** + * + */ + static public Object getCookieValue (Cookie[] cookies, String key) + { + Object result; + + Cookie cookie = getCookie(cookies, key); + + if (cookie == null) + { + result = null; + } + else + { + result = cookie.getValue(); + } + + // + return(result); + } + + + /** + * + */ + public String userId(HttpServletRequest request) + { + String result; + + result = (String) getCookieValue(request.getCookies (), this.userIdLabel); + + // + return(result); + } + + + /** + * + */ + public String accountId(HttpServletRequest request) + { + String result; + + result = (String) getCookieValue(request.getCookies (), this.accountIdLabel); + + // + return(result); + } + + + + /** + * + */ + public String auth(HttpServletRequest request) + { + String result; + + result = (String) getCookieValue(request.getCookies (), this.authLabel); + + // + return(result); + } + + + /** + * Check authentication and refresh it (reset countdown). + */ + public boolean isAuthenticated (HttpServletRequest request, HttpServletResponse response) + { + boolean result; + + String accountId = accountId(request); + String userId = userId(request); + String auth = auth(request); + logger.info("cook=[" + auth + "]"); + + if (auth == null) + { + result = false; + } + else if (auth.equals(computeAuth(accountId, userId, request.getRemoteAddr(), this.secretKey))) + { + result = true; + + // Refresh cookies. + setAuthenticated(request, response, accountId, userId); + } + else + { + result = false; + } + + // + return (result); + } + + + /** + * + */ + static public String computeAuth(String key1, String key2, String key3, String key4) + { + String result; + + result = md5sum(key1 + key2 + key3+ key4); + + // + return(result); + } + + /** + * + */ + public void setAuthenticated (HttpServletRequest request, HttpServletResponse response, String accountId, String userId) + { + // Refresh cookie. + int duration = 60*60; + String auth = computeAuth(String.valueOf(accountId), userId, request.getRemoteAddr(), this.secretKey); + response.addCookie (buildCookie(this.authLabel, auth, duration)); + response.addCookie (buildCookie(this.accountIdLabel, accountId, duration)); + response.addCookie (buildCookie(this.userIdLabel, userId, duration)); + + logger.info("set [" + auth + "," + accountId + "," + userId + "," + request.getRemoteAddr() + ")"); + } + + + /** + * + */ + public void reset(HttpServletRequest request, HttpServletResponse response) + { + response.addCookie(buildCookie(this.authLabel, "", 0)); + response.addCookie(buildCookie(this.accountIdLabel, "", 0)); + response.addCookie(buildCookie(this.userIdLabel, "", 0)); + } +} \ No newline at end of file diff --git a/src/fr/devinsy/xidvc/Page.java b/src/fr/devinsy/xidvc/Page.java new file mode 100644 index 0000000..74f0d72 --- /dev/null +++ b/src/fr/devinsy/xidvc/Page.java @@ -0,0 +1,18 @@ +package fr.devinsy.xidvc; +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; + + + +/** + * + */ +public interface Page +{ + /** + * + */ + public void doIt (HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException; +} diff --git a/src/fr/devinsy/xidvc/PageManager.java b/src/fr/devinsy/xidvc/PageManager.java new file mode 100644 index 0000000..cf59bfc --- /dev/null +++ b/src/fr/devinsy/xidvc/PageManager.java @@ -0,0 +1,392 @@ +package fr.devinsy.xidvc; + +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; +import fr.devinsy.xidvc.security.*; + +/** + * + */ +public class PageManager extends HttpServlet +{ + private static final long serialVersionUID = 1983715791417570578L; + private static PageManager instance = null; + protected SecurityAgent securityAgent; + + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (PageManager.class); + + /** + * + */ + public void init () throws ServletException + { + // + instance = this; + + this.securityAgent = new SecurityAgent (getInitParameter ("securityDataPath")); + } + + /** + * + */ + public static PageManager instance () + { + return instance; + } + + /** + * + */ + static public String buildClassName (String pathInfo) + { + String result; + result = null; + + if ( pathInfo.equals ("/")) + { + result = "Accueil"; + } + else + { + String[] tokens = pathInfo.split ("/"); + StringBuffer name = new StringBuffer (); + + for (int tokenCounter = 1; tokenCounter < tokens.length - 1; tokenCounter++) + { + name.append (tokens[tokenCounter]); + name.append ('.'); + } + + if (pathInfo.endsWith ("/")) + { + name.append (tokens[tokens.length - 1]); + name.append ('.'); + } + + logger.info ("==>[" + tokens[tokens.length - 1] + "]"); + name.append (formatClassName (tokens[tokens.length - 1])); + + result = name.toString (); + } + + // + return (result); + } + + /** + * + */ + static public String buildClassName2 (String pathInfo) + { + String result; + + if (pathInfo.endsWith (".xhtml")) + { + char[] source = pathInfo.toCharArray (); + + StringBuffer out = new StringBuffer (); + for (char c : source) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + + char[] target = new char[source.length - 7]; + int lastStartToken = 0; + for (int nChar = 1; nChar < source.length - 5; nChar++) + { + char charSource = source[nChar]; + switch (charSource) + { + case '/': + target[nChar - 1] = '.'; + lastStartToken = nChar; + break; + + case '.': + target[lastStartToken] = Character.toUpperCase (target[lastStartToken]); + break; + + default: + target[nChar - 1] = source[nChar]; + } + } + + out = new StringBuffer (); + for (char c : target) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + + result = new String (target); + } + else if (pathInfo.equals ("/")) + { + result = "Accueil"; + } + else if (pathInfo.endsWith ("/")) + { + char[] source = pathInfo.toCharArray (); + + StringBuffer out = new StringBuffer (); + for (char c : source) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + + char[] target = new char[source.length - 2]; + int lastStartToken = 0; + for (int nChar = 1; nChar < source.length - 1; nChar++) + { + char charSource = source[nChar]; + switch (charSource) + { + case '/': + target[nChar - 1] = '.'; + lastStartToken = nChar + 1; + break; + + default: + target[nChar - 1] = source[nChar]; + } + } + + char[] targetPlus = new char [source.length - lastStartToken]; + targetPlus[0] = '.'; + targetPlus[1] = Character.toUpperCase (source[lastStartToken]); + int index = 2; + for (int nChar = lastStartToken + 1; nChar < source.length - 1; nChar++) + { + targetPlus[index] = source[nChar]; + index += 1; + } + + out = new StringBuffer (); + for (char c : target) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + out = new StringBuffer (); + for (char c : targetPlus) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + + result = new String (target) + new String (targetPlus); + } + else + { + logger.debug ("unknow case"); + result = null; + } + + // + return (result); + } + + + /** + */ + public Page instanciatePage (String className) + { + Page result; + + Class pageClass = null; + try + { + pageClass = (Class) Class.forName (className); + } + catch (java.lang.ClassNotFoundException exception) + { + result = null; + } + + logger.info ("class=" + pageClass); + + if (pageClass == null) + { + result = null; + logger.error ("Unknow page: (" + className + ")"); + } + else + { + try + { + result = pageClass.newInstance (); + } + catch (java.lang.InstantiationException exception) + { + logger.error ("Can't instanciate page (" + className + ")"); + result = null; + } + catch (java.lang.IllegalAccessException exception) + { + logger.error ("(2) Can't instanciate page (" + className + ")"); + result = null; + } + } + + // + return (result); + } + + /** + * + */ + public void doGet (HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException + { + logger.info ("=================================================="); + logger.info ("getContextPath=[" + request.getContextPath () + "]"); + logger.info ("getPathInfo=[" + request.getPathInfo () + "]"); + logger.info ("getPathTranslated=[" + request.getPathTranslated () + "]"); + logger.info ("getQueryString=[" + request.getQueryString () + "]"); + logger.info ("getRequestURI=[" + request.getRequestURI () + "]"); + logger.info ("getRequestURL=[" + request.getRequestURL () + "]"); + logger.info ("getServletPath=[" + request.getServletPath () + "]"); + + String className = buildClassName (request.getPathInfo ()); + logger.info ("className=" + className); + + Page page = this.instanciatePage ("site." + className); + + if (page == null) + { + response.setContentType ("text/html"); + PrintWriter out = response.getWriter(); + + out.println ("Unknow page."); + } + else + { + HttpSession session = request.getSession (false); + String login; + if (session == null) + { + login = null; + } + else + { + login = (String) session.getAttribute ("login"); + } + + if (this.securityAgent.checkPermission (request.getPathInfo (), login)) + { + page.doIt (request, response); + logger.info ("securityAgent say 'permission OK': (" + login + ", " + request.getPathInfo () + ")"); + } + else + { + logger.info ("securityAgent say 'permission KO': (" + login + ", " + request.getPathInfo () + ")"); + + if (login == null) + { + response.sendRedirect ("/gestion/login.xhtml"); + } + else + { + response.setContentType ("text/html"); + PrintWriter out = response.getWriter(); + + out.println (""); + out.println ("Permission denied."); + out.println ("
"); + out.println (" "); + out.println ("
"); + out.println (""); + } + } + } + } + + + /** + * + */ + public void doPost (HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + doGet (request, response); + } + + + /** + * + */ + static public String formatClassName (String name) + { + String result; + + result = null; + + String[] splittedLastToken = name.split ("\\."); + String last = splittedLastToken[0]; + //logger.info ("last=" + last); + + String[] tokens = last.split ("_"); + StringBuffer all = new StringBuffer (); + for (String token : tokens) + { + //logger.info ("tok=" + token); + + all.append (Character.toUpperCase (token.charAt (0))); + all.append (token.substring (1)); + } + + result = all.toString (); + + // + return (result); + } + + + /** + * + */ + public SecurityAgent securityAgent () + { + SecurityAgent result; + + result = this.securityAgent; + + // + return (result); + } + + + /** + * + */ + static public User getUserFromSession (HttpServletRequest request) + { + User result; + + if (request == null) + { + result = null; + } + else + { + HttpSession session = request.getSession (false); + + String login; + if (session == null) + { + result = null; + } + else + { + login = (String) session.getAttribute ("login"); + result = PageManager.instance ().securityAgent ().users ().getByLogin (login); + } + } + + // + return (result); + } +} diff --git a/src/fr/devinsy/xidvc/ServletDispatcher.java b/src/fr/devinsy/xidvc/ServletDispatcher.java new file mode 100644 index 0000000..1add427 --- /dev/null +++ b/src/fr/devinsy/xidvc/ServletDispatcher.java @@ -0,0 +1,71 @@ +/** + * @author Christian Momon, June 2008. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ + +package fr.devinsy.xidvc; + +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; + + + +/** + * + */ +public class ServletDispatcher extends SimpleServletDispatcher +{ + private static final long serialVersionUID = -3471226305721330069L; + protected org.apache.log4j.Logger logger; + //protected Servlets servlets; + + + /** + * + */ + public void init () throws ServletException + { + super.init(); + this.logger = org.apache.log4j.Logger.getLogger (this.getClass()); + //this.servlets = new Servlets(); + } + + + /** + * + */ + public void doIt (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + logger.info ("=================================================="); + logger.info ("getContextPath=[" + request.getContextPath () + "]"); + logger.info ("getPathInfo=[" + request.getPathInfo () + "]"); + logger.info ("getPathTranslated=[" + request.getPathTranslated () + "]"); + logger.info ("getQueryString=[" + request.getQueryString () + "]"); + logger.info ("getRequestURI=[" + request.getRequestURI () + "]"); + logger.info ("getRequestURL=[" + request.getRequestURL () + "]"); + logger.info ("getServletPath=[" + request.getServletPath () + "]"); + + String className = pathInfoToClassName (request.getPathInfo ()); + logger.info ("className=" + className); + + HttpServlet servlet = instanciateServlet (className); + + if (servlet == null) + { + response.setContentType ("text/html"); + PrintWriter out = response.getWriter(); + + out.println (""); + out.println ("Unknow page."); + out.println (""); + + out.close(); + } + else + { + servlet.service(request, response); + } + } +} diff --git a/src/fr/devinsy/xidvc/SimpleServletDispatcher.java b/src/fr/devinsy/xidvc/SimpleServletDispatcher.java new file mode 100644 index 0000000..01174e5 --- /dev/null +++ b/src/fr/devinsy/xidvc/SimpleServletDispatcher.java @@ -0,0 +1,276 @@ +/** + * @author Christian Momon, June 2008. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ + +package fr.devinsy.xidvc; + +import java.io.*; +import java.util.Enumeration; + +import javax.servlet.*; +import javax.servlet.http.*; + +import fr.devinsy.util.StringConcatenator; + + +/** + * + */ +public class SimpleServletDispatcher extends HttpServlet +{ + private static final long serialVersionUID = -3471226305721330069L; + static protected org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (ServletDispatcher.class); + protected String pathInfoClassNamePrefix; + + + /** + * + */ + public void init () throws ServletException + { + super.init(); + this.pathInfoClassNamePrefix = getInitParameter("pathInfoClassNamePrefix"); + + // Set logger. + String logFilepathname = getInitParameter("log4j-init-file"); + if (logFilepathname != null) + { + try + { + System.out.println("Log configuration found (" + logFilepathname + "), will use it."); + org.apache.log4j.PropertyConfigurator.configure (getServletContext().getRealPath("/") + logFilepathname); + } + catch (Exception exception) + { + System.out.println("Log configuration FILE NOT FOUND (" + logFilepathname + "), use of the basic configurator."); + org.apache.log4j.BasicConfigurator.configure(); + } + + logger = org.apache.log4j.Logger.getLogger(this.getClass()); + logger.info("Log initialization done."); + } + } + + + /** + * "/" => "Index_xhtml" + * "/good/" => "good.Good_xhtml" + * "/good/morning.xhtml" => "good.Morning_xhtml" + * "/good/day_day.xhtml" => "good.Day_day_xhtml" + */ + static public String pathInfoToClassName (String pathInfo) + { + String result; + + if ((pathInfo == null) || (pathInfo.length() == 0)) + { + result = null; + } + else + { + if ( pathInfo.equals ("/")) + { + result = "Index_xhtml"; + } + else + { + String[] tokens = pathInfo.split ("/"); + StringConcatenator name = new StringConcatenator(); + + for (int tokenCounter = 1; tokenCounter < tokens.length - 1; tokenCounter++) + { + name.append (tokens[tokenCounter]); + name.append ('.'); + } + + String lastToken = tokens[tokens.length - 1]; + if (pathInfo.endsWith ("/")) + { + name.append(lastToken).append(".").append(lastToken.substring(0, 1).toUpperCase()).append(lastToken.substring(1)).append("_xhtml"); + } + else + { + name.append (lastToken.substring(0, 1).toUpperCase()).append (lastToken.substring(1).replace('.', '_')); + } + + result = name.toString (); + logger.debug ("==>[" + tokens[tokens.length - 1] + "]"); + } + } + + logger.info ("[" + pathInfo + "] => [" + result + "]"); + + // + return (result); + } + + + /** + * + */ + static public String pathInfoToClassName (String pathInfo, String prefix) + { + String result; + + if (prefix == null) + { + result = pathInfoToClassName(pathInfo); + } + else if (prefix.endsWith(".")) + { + result = prefix + pathInfoToClassName(pathInfo); + } + else + { + result = prefix + "." + pathInfoToClassName(pathInfo); + } + + // + return (result); + } + + + /** + * + */ + static public HttpServlet instanciateServlet (String className) + { + HttpServlet result; + + Class servletClass = null; + try + { + servletClass = (Class) Class.forName (className); + } + catch (java.lang.ClassNotFoundException exception) + { + result = null; + } + + logger.info ("class=" + servletClass); + + if (servletClass == null) + { + result = null; + logger.error ("Unknow page: (" + className + ")"); + } + else + { + try + { + result = servletClass.newInstance (); + } + catch (java.lang.InstantiationException exception) + { + logger.error ("Can't instanciate servlet (" + className + ")"); + result = null; + } + catch (java.lang.IllegalAccessException exception) + { + logger.error ("(2) Can't instanciate servlet (" + className + ")"); + result = null; + } + } + + // + return (result); + } + + + /** + * + */ + public boolean isAuthorized(HttpServletRequest request, HttpServletResponse response) + { + boolean result; + + result = true; + + // + return(result); + } + + /** + * + */ + public void doIt (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + logger.info ("=================================================="); + logger.info ("getContextPath=[" + request.getContextPath () + "]"); + logger.info ("getPathInfo=[" + request.getPathInfo () + "]"); + logger.info ("getPathTranslated=[" + request.getPathTranslated () + "]"); + logger.info ("getQueryString=[" + request.getQueryString () + "]"); + logger.info ("getRequestURI=[" + request.getRequestURI () + "]"); + logger.info ("getRequestURL=[" + request.getRequestURL () + "]"); + logger.info ("getServletPath=[" + request.getServletPath () + "]"); + + // + String path; + if (request.getPathInfo() == null) + { + // web.xml url-pattern= *.xhtml + path = request.getServletPath(); + } + else + { + // web.xml url-pattern = /* + path = request.getPathInfo(); + } + + String className = pathInfoToClassName (path, this.pathInfoClassNamePrefix); + logger.info ("className=" + className); + + HttpServlet servlet = instanciateServlet (className); + + + //servlet.getServletContext().setAttribute(arg0, arg1); + + if (servlet == null) + { + response.setContentType ("text/html"); + PrintWriter out = response.getWriter(); + + out.println (""); + out.println ("Unknow page."); + out.println (""); + + out.close(); + } + else if (isAuthorized(request, response)) + { + servlet.service(request, response); + } + else + { +/* + // + response.setContentType ("text/html"); + PrintWriter out = response.getWriter(); + + out.println (""); + out.println ("Not authorized page."); + out.println (""); + */ + } + } + + + /** + * + */ + public void doGet (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + doIt (request, response); + } + + + /** + * + */ + public void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + doIt (request, response); + } +} diff --git a/src/fr/devinsy/xidvc/security/Group.java b/src/fr/devinsy/xidvc/security/Group.java new file mode 100644 index 0000000..e9ef33a --- /dev/null +++ b/src/fr/devinsy/xidvc/security/Group.java @@ -0,0 +1,101 @@ +package fr.devinsy.xidvc.security; + + +import java.util.*; + +/** + * + */ +public class Group +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (Group.class); + + protected String name; + protected Vector members; + + + /** + * + */ + public Group () + { + this.name = null; + this.members = new Vector (); + } + + + /** + * + */ + public void addMember (String login) + { + if ((login != null) && (login.length () != 0)) + { + this.members.add (login); + } + } + + + /** + * + */ + public boolean contains (String name) + { + boolean result = false; + + result = this.members.contains (name); + + // + return (result); + } + + /** + * + */ + public Vector members () + { + Vector result; + + result = this.members; + + // + return (result); + } + + + /** + * + */ + public String name () + { + String result; + + result = this.name; + + // + return (result); + } + + /** + * + */ + public void setName (String name) + { + this.name = name; + } + + /** + * + */ + public String toString () + { + String result; + + result = "|" + this.name + "|" + this.members + "|"; + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/xidvc/security/Groups.java b/src/fr/devinsy/xidvc/security/Groups.java new file mode 100644 index 0000000..e60019a --- /dev/null +++ b/src/fr/devinsy/xidvc/security/Groups.java @@ -0,0 +1,165 @@ +package fr.devinsy.xidvc.security; + + +import java.util.*; + +/** + * + */ +public class Groups extends Vector +{ + private static final long serialVersionUID = 6238581648850758903L; + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (Groups.class); + + + /** + * + */ + public Groups () + { + super (); + } + + + /** + * + */ + public Group get (String name) + { + Group result; + + if (name == null) + { + result = null; + } + else + { + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + Group group = iterator.next (); + if (group.name ().equals (name)) + { + ended = true; + result = group; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (String name) + { + boolean result; + + if (get (name) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + /** + * + */ + public Vector getLoginGroups (String login) + { + Vector result; + + result = new Vector (); + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + Group group = iterator.next (); + + if (group.members ().contains (login)) + { + result.add (group.name ()); + } + } + + // + return (result); + } + + + /** + * + */ + public String getLoginGroupsString (String login) + { + String result; + + Vector groups = getLoginGroups (login); + + StringBuffer string = new StringBuffer (); + + for (String group : groups) + { + if (string.length () == 0) + { + string.append (group); + } + else + { + string.append (","); + string.append (group); + } + } + + result = string.toString (); + + // + return (result); + } + + + /** + * + */ + public String toString () + { + String result; + + StringBuffer out; + out = new StringBuffer (); + + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + out.append (iterator.next ().toString () + "\n"); + } + + result = out.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/xidvc/security/GroupsFileReader.java b/src/fr/devinsy/xidvc/security/GroupsFileReader.java new file mode 100644 index 0000000..1b76acc --- /dev/null +++ b/src/fr/devinsy/xidvc/security/GroupsFileReader.java @@ -0,0 +1,58 @@ +package fr.devinsy.xidvc.security; + +import java.io.*; +import java.util.*; + + +/** + * + */ +public class GroupsFileReader +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (GroupsFileReader.class); + + + /** + * + */ + static public Groups load (String fileName) + { + Groups result; + + result = new Groups (); + + Properties properties = new Properties(); + try + { + properties.load (new FileInputStream(fileName)); + + Iterator iterator = properties.keySet ().iterator (); + while (iterator.hasNext ()) + { + String key = (String) iterator.next (); + String valueLine = (String) properties.get (key); + + // + String[] values = valueLine.split (","); + + Group group = new Group (); + group.setName (key); + for (String value : values) + { + group.addMember (value.trim ()); + } + + result.add (group); + } + } + catch (Exception e) + { + logger.fatal ("can't load (" + fileName + ")"); + } + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/xidvc/security/SecurityAgent.java b/src/fr/devinsy/xidvc/security/SecurityAgent.java new file mode 100644 index 0000000..464ffdb --- /dev/null +++ b/src/fr/devinsy/xidvc/security/SecurityAgent.java @@ -0,0 +1,154 @@ +package fr.devinsy.xidvc.security; + + +import java.util.*; + + + +/** + * + */ +public class SecurityAgent +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (SecurityAgent.class); + + protected Users users; + protected Groups groups; + protected Groups permissions; + + + /** + * + */ + public SecurityAgent (String path) + { + this.users = UsersFileReader.load (path + "users.conf"); + this.groups = GroupsFileReader.load (path + "groups.conf"); + this.permissions = GroupsFileReader.load (path + "permissions.conf"); + } + + + /** + * + */ + public Groups groups () + { + Groups result; + + result = this.groups; + + // + return (result); + } + + /** + * + */ + public Groups permissions () + { + Groups result; + + result = this.permissions; + + // + return (result); + } + + /** + * + */ + public Users users () + { + Users result; + + result = this.users; + + // + return (result); + } + + /** + * + */ + public boolean authenticate (String login, String password) + { + boolean result; + + User user = this.users.getByLogin (login); + + if (user == null) + { + logger.info ("unknow login try to connect."); + result = false; + } + else if (user.password ().equals (password)) + { + result = true; + } + else + { + result = false; + } + + // + return (result); + } + + /** + * + */ + public boolean checkPermission (String url, String login) + { + boolean result = false; + + Group permitGroups = this.permissions.get (url); + + if (permitGroups == null) + { + result = false; + } + else + { + // + boolean ended = false; + Iterator iterator = permitGroups.members ().iterator (); + while (!ended) + { + if (!iterator.hasNext ()) + { + ended = true; + result = false; + } + else + { + String groupName = iterator.next (); + if (groupName.equals ("*")) + { + result = true; + ended = true; + } + else + { + Group members = this.groups.get (groupName); + + if (members == null) + { + result = false; + } + else + { + if (members.contains (login)) + { + ended = true; + result = true; + } + } + } + } + } + } + + // + return (result); + } +} diff --git a/src/fr/devinsy/xidvc/security/User.java b/src/fr/devinsy/xidvc/security/User.java new file mode 100644 index 0000000..ca456ae --- /dev/null +++ b/src/fr/devinsy/xidvc/security/User.java @@ -0,0 +1,129 @@ +package fr.devinsy.xidvc.security; + + + + +/** + * + */ +public class User +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (User.class); + + protected String login; + protected String password; + protected String realName; + protected String email; + + + /** + * + */ + public User () + { + this.login = null; + this.password = null; + this.realName = null; + this.email = null; + } + + + /** + * + */ + public String email () + { + String result; + + result = this.email; + + // + return (result); + } + + /** + * + */ + public String login () + { + String result; + + result = this.login; + + // + return (result); + } + + /** + * + */ + public String password () + { + String result; + + result = this.password; + + // + return (result); + } + + /** + * + */ + public String realName () + { + String result; + + result = this.realName; + + // + return (result); + } + + + /** + * + */ + public void setEmail (String email) + { + this.email = email; + } + + /** + * + */ + public void setLogin (String login) + { + this.login = login; + } + + /** + * + */ + public void setPassword (String password) + { + this.password = password; + } + + /** + * + */ + public void setRealName (String realName) + { + this.realName = realName; + } + + /** + * + */ + public String toString () + { + String result; + + result = "|" + this.login + "|" + this.password + "|" + this.realName + "|"; + + // + return (result); + } +} + diff --git a/src/fr/devinsy/xidvc/security/Users.java b/src/fr/devinsy/xidvc/security/Users.java new file mode 100644 index 0000000..3321609 --- /dev/null +++ b/src/fr/devinsy/xidvc/security/Users.java @@ -0,0 +1,110 @@ +package fr.devinsy.xidvc.security; + + +import java.util.*; + + +/** + * + */ +public class Users extends Vector +{ + private static final long serialVersionUID = 6140538630004281217L; + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (Users.class); + + + /** + * + */ + public Users () + { + super (); + } + + + /** + * + */ + public User getByLogin (String login) + { + User result; + + if (login == null) + { + result = null; + } + else + { + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + User user = iterator.next (); + if (user.login ().equals (login)) + { + ended = true; + result = user; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (String login) + { + boolean result; + + if (getByLogin (login) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + /** + * + */ + public String toString () + { + String result; + + StringBuffer out; + out = new StringBuffer (); + + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + out.append (iterator.next ().toString () + "\n"); + } + + result = out.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/xidvc/security/UsersFileReader.java b/src/fr/devinsy/xidvc/security/UsersFileReader.java new file mode 100644 index 0000000..6fca6c2 --- /dev/null +++ b/src/fr/devinsy/xidvc/security/UsersFileReader.java @@ -0,0 +1,59 @@ +package fr.devinsy.xidvc.security; + +import java.io.*; +import java.util.*; + + +/** + * + */ +public class UsersFileReader +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (UsersFileReader.class); + + + /** + * + */ + static public Users load (String fileName) + { + Users result; + + result = new Users (); + + Properties properties = new Properties(); + try + { + properties.load (new FileInputStream(fileName)); + + Iterator iterator = properties.keySet ().iterator (); + while (iterator.hasNext ()) + { + String key = (String) iterator.next (); + String valueLine = (String) properties.get (key); + + // + String[] values = valueLine.split (","); + + User user = new User (); + user.setLogin (key); + user.setPassword (values[0]); + user.setRealName (values[1]); + user.setEmail (values[2]); + + result.add (user); + // + } + } + catch (Exception e) + { + logger.fatal ("can't load (" + fileName + ")"); + } + + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/tests/Test.java b/tests/Test.java new file mode 100644 index 0000000..57e35ce --- /dev/null +++ b/tests/Test.java @@ -0,0 +1,242 @@ +import java.util.regex.Pattern; + +import fr.devinsy.xid.Data; +import fr.devinsy.xid.IdData; +import fr.devinsy.xid.StringPresenter; + +/** + * Devinsy-utils tests. + */ + + + +/** + * + */ +class XidTest +{ + static private org.apache.log4j.Logger logger; + + static + { + // Initialize logger. + org.apache.log4j.Logger log = null; + + org.apache.log4j.BasicConfigurator.configure (); + + + log = org.apache.log4j.Logger.getRootLogger (); + //logger.setLevel (org.apache.log4j.Level.INFO); + logger.setLevel (org.apache.log4j.Level.INFO); + + logger.info ("Enter"); + + // + logger.info ("Set the log file format..."); + + + // log = org.apache.log4j.Category.getInstance(Application.class.getName()); + logger.info ("... done."); + + logger.debug ("Exit"); + log = org.apache.log4j.Logger.getLogger (XidTest.class.getName ()); + } + + + + /** + * + */ + public static String check (String title, StringBuffer source, String model) + { + String result; + + if (source.indexOf (model) == -1) + { + result = String.format ("%-40s -> KO <-", title) + "\nGet:\n" + source + "\nWaiting:\n" + model; + + } + else + { + result = String.format ("%-40s [ OK ] ", title); + } + + + // + return (result); + } + + public enum MONTHS {JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBRE, DECEMBRE}; + + /** + * + */ + public static void main(String[] args) + { + System.out.println("Automatic test action for Xid!"); + + Data datas; + IdData tag; + + + String htmlSource; + StringBuffer html; + StringBuffer errorMessage; + + // Populate attributes of Test 03. + System.out.println ("----------------------------"); + datas = new Data (); + datas.setContent ("name", "Superman"); + errorMessage = new StringBuffer (); + + html = StringPresenter.doXid ("
a name
", datas, errorMessage); + + System.out.println (check ("only content change", html, "
Superman
")); + + + // Populate attributes of Test 03. + System.out.println ("----------------------------"); + datas = new Data (); + datas.setContent ("lastname", "Spiderman"); + datas.appendAttribute ("lastname", "style", "background: blue;"); + datas.appendAttribute ("lastname", "style", "foreground: red;"); + datas.setAttribute ("lastname", "class", "nameClass"); + + errorMessage = new StringBuffer (); + html = StringPresenter.doXid ("
a last name
", datas, errorMessage); + System.out.println (check ("content and attributes", html, "
Spiderman
")); + + // Populate attributes of Test 03. + System.out.println ("----------------------------"); + datas = new Data (); + datas.setContent ("words", 0, "alpha"); + datas.setContent ("words", 1, "bravo"); + datas.setContent ("words", 2, "charlie"); + datas.setContent ("words", 3, "delta"); + datas.setContent ("words", 4, "echo"); + datas.setContent ("words", 5, "fox"); + + + errorMessage = new StringBuffer (); + html = StringPresenter.doXid ("
    \n
  • a word
  • \n
", datas, errorMessage); + + System.out.println (check ("list assertion 1", html, "
  • alpha
  • ")); + System.out.println (check ("list assertion 2", html, "
  • bravo
  • ")); + System.out.println (check ("list assertion 3", html, "
  • charlie
  • ")); + System.out.println (check ("list assertion 4", html, "
  • delta
  • ")); + System.out.println (check ("list assertion 5", html, "
  • echo
  • ")); + System.out.println (check ("list assertion 6", html, "
  • fox
  • ")); + + // Populate attributes of Test 03. + System.out.println ("----------------------------"); + datas = new Data (); + datas.setContent ("identity", 0, "nom", "Jemba"); + datas.setContent ("identity", 0, "prenom", "Epo"); + datas.setContent ("identity", 1, "nom", "Momon"); + datas.setContent ("identity", 1, "prenom", "Christian"); + datas.setContent ("identity", 2, "nom", "Tronche"); + datas.setContent ("identity", 2, "prenom", "Christophe"); + + + errorMessage = new StringBuffer (); + StringBuffer source = new StringBuffer (); + source.append ("\n"); + source.append (" \n"); + source.append ("
    noidun nomun prenom
    "); + htmlSource = source.toString (); + html = StringPresenter.doXid (htmlSource, datas, errorMessage); + + System.out.println (check ("table 1 assertion 1", html, "noidJembaEpo")); + System.out.println (check ("table 1 assertion 2", html, "noidMomonChristian")); + System.out.println (check ("table 1 assertion 3", html, "noidTroncheChristophe")); + + /* + // Populate attributes of Test 03. + System.out.println ("----------------------------"); + datas = new Data (); + datas.setContent ("identity", 0, "nom", "Jemba"); + datas.setContent ("identity", 0, "prenom", "Epo"); + datas.setContent ("identity", 1, "nom", "Momon"); + datas.setContent ("identity", 1, "prenom", "Christian"); + datas.setContent ("identity", 2, "nom", "Tronche"); + datas.setContent ("identity", 2, "prenom", "Christophe"); + datas.setIterationStrategy ("identity", IdsDataByIndex.IterationStrategy.ONLY_FIRST_ROW); + //datas.setIterationStrategy ("identity", IdsDataByIndex.IterationStrategy.ONLY_ROWS_WITH_ID); + //datas.setIterationStrategy ("identity", IdsDataByIndex.IterationStrategy.ONLY_ROWS_WITHOUT_ID); + //datas.setIterationStrategy ("identity", IdsDataByIndex.IterationStrategy.ALL_ROWS); + + + errorMessage = new StringBuffer (); + source = new StringBuffer (); + source.append ("\n"); + source.append (" \n"); + source.append (" \n"); + source.append (" \n"); + source.append ("
    noidun nomun prenom
    noidun nomun prenom
    noidun nomun prenom
    "); + htmlSource = source.toString (); + + System.out.println ("datas = new Data ();"); + System.out.println ("datas.setContent (\"identity\", 0, \"nom\", \"Jemba\");"); + System.out.println ("datas.setContent (\"identity\", 0, \"prenom\", \"Epo\");"); + System.out.println ("datas.setContent (\"identity\", 1, \"nom\", \"Momon\");"); + System.out.println ("datas.setContent (\"identity\", 1, \"prenom\", \"Christian\");"); + System.out.println ("datas.setContent (\"identity\", 2, \"nom\", \"Tronche\");"); + System.out.println ("datas.setContent (\"identity\", 2, \"prenom\", \"Christophe\");"); + + System.out.println ("+"); + System.out.println (htmlSource); + System.out.println ("=>"); + + + datas.setIterationStrategy ("identity", IdsDataByIndex.IterationStrategy.ONLY_FIRST_ROW); + System.out.println ("ONLY_FIRST_ROW:"); + html = Presenter.doXid (htmlSource, datas, "", errorMessage); + System.out.println (html); + + datas.setIterationStrategy ("identity", IdsDataByIndex.IterationStrategy.ONLY_ROWS_WITH_ID); + System.out.println ("ONLY_ROWS_WITH_ID:"); + html = Presenter.doXid (htmlSource, datas, "", errorMessage); + System.out.println (html); + + datas.setIterationStrategy ("identity", IdsDataByIndex.IterationStrategy.ONLY_ROWS_WITHOUT_ID); + System.out.println ("ONLY_ROWS_WITHOUT_ID:"); + html = Presenter.doXid (htmlSource, datas, "", errorMessage); + System.out.println (html); + + datas.setIterationStrategy ("identity", IdsDataByIndex.IterationStrategy.ALL_ROWS); + System.out.println ("ALL_ROWS:"); + html = Presenter.doXid (htmlSource, datas, "", errorMessage); + System.out.println (html); + + + + // Populate attributes of Test 03. + System.out.println ("----------------------------"); + datas = new Data (); + datas.setAttribute ("
    ", "class", "aDivClass"); + datas.setAttribute ("
    ", "style", "background-color: #000000;"); + datas.setAttribute ("number", "style", "background-color: #0000FF;"); + + errorMessage = new StringBuffer (); + source = new StringBuffer (); + source.append ("
    \n"); + source.append ("

    one

    \n"); + source.append ("
    \n"); + source.append ("
    \n"); + source.append ("

    three

    \n"); + source.append ("
    "); + htmlSource = source.toString (); + html = Presenter.doXid (htmlSource, datas, "", errorMessage); + + System.out.println (htmlSource); + System.out.println ("+"); + System.out.println ("datas = new Data ();"); + System.out.println ("datas.setAttribute (\"
    \", \"class\", \"aDivClass\");"); + System.out.println ("datas.setAttribute (\"
    \", \"style\", \"background-color: #000000;\");"); + System.out.println ("datas.setAttribute (\"number\", \"style\", \"background-color: #0000FF;\");"); + + System.out.println ("=>"); + System.out.println (html); + */ + } +}