Author: jcouteau Date: 2009-07-30 16:05:04 +0200 (Thu, 30 Jul 2009) New Revision: 116 Modified: trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java trunk/src/main/java/org/nuiton/j2r/types/RList.java Log: Remove duplicate code, improve code (for sonar :) ) Modified: trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java 2009-07-26 17:11:04 UTC (rev 115) +++ trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java 2009-07-30 14:05:04 UTC (rev 116) @@ -19,8 +19,10 @@ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; +import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; @@ -41,6 +43,19 @@ private List<String> rowNames; //Vector containing the vectors of the data.frame private List<List<? extends Object>> data; + private String setNamesString = "names(%s)<-c(%s)"; + private String setNameString = "names(%s)[%s]<-\"%s\""; + private String getNamesString = "names(%s)"; + private String getNameString = "names(%s)[%s]"; + private String getRowNamesString = "row.names(%s)"; + private String getRowNameString = "row.names(%s)[%s]"; + private String setRowNamesString = "row.names(%s)<-c(%s)"; + private String setRowNameString = "row.names(%s)[%s]<-\"%s\""; + private String indexExceptionText = + "Cannot perform operation, index is superior to size.\nIndex : %s\nSize : %s"; + private String dataInconsistencyText = + "There is an inconsistency between the local and distant data.\nLocal data size : %s\nDistant data size : %s"; + private String noVariable = "No variable name given"; public RDataFrame(REngine engine) throws RException { super(); @@ -121,12 +136,12 @@ * when the row.names size get from R is bigger than the local * data size. */ - public List<String> getNames() throws RException, IndexOutOfBoundsException { + public List<String> getNames() throws RException { if (engine.isAutoCommit()) { //Get back the names from R. - String[] namesArray = (String[]) engine.eval("names(" + - this.variable + ")"); + String[] namesArray = (String[]) engine.eval(String.format( + getNamesString, this.variable)); //Check if size is correct, if yes, modify local data. if (namesArray.length <= this.data.size()) { @@ -137,11 +152,10 @@ return names; } else { //if size is not correct, throw a RException. - throw new IndexOutOfBoundsException( - "Data inconsistency, local data is smaller (size : " + - this.data.size() + - ") than the names ArrayList in R (size : " + - namesArray.length + ")"); + throw new IndexOutOfBoundsException(String.format( + dataInconsistencyText, this.data.size(), + namesArray.length)); + } } else { return this.names; @@ -164,14 +178,14 @@ * @throws IndexOutOfBoundsException * if the x index is out of bounds. */ - public String getName(int x) throws RException, IndexOutOfBoundsException { + public String getName(int x) throws RException { //check if the index is valid if (x < names.size()) { if (engine.isAutoCommit()) { //Get back the names from R. - String name = (String) engine.eval("names(" + this.variable + - ")[" + (x + 1) + "]"); + String name = (String) engine.eval(String.format(getNameString, + this.variable, x + 1)); //Check if the String is returned. if ((name != null) && (!name.equals(""))) { @@ -180,7 +194,8 @@ } } else { //if String is not returned, throw an IndexOutOfBOundsException. - throw new IndexOutOfBoundsException("Your index is not valid"); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, this.names.size())); } return this.names.get(x); @@ -197,29 +212,31 @@ * when the names ArrayList is longer than the data.frame * length. */ - public void setNames(List<String> names) throws RException, - IndexOutOfBoundsException { + public void setNames(List<String> names) throws RException { //Check if the size is correct, if yes, do the modifications and send them to R. if (names.size() <= data.size()) { this.names = names; //Create the r instruction (names(var)<-c("name 1",...,"name x")). - String rexp = "names(" + this.variable + ")<-c("; + + String namesString = ""; for (int i = 0; i < this.names.size(); i++) { - rexp += "\"" + names.get(i) + "\","; + //add a "," to separate names beginning after the first name is displayed. + if (i != 0) { + namesString += ","; + } + //add the column name between quotes. + namesString += "\"" + names.get(i) + "\""; } - rexp = rexp.substring(0, rexp.length() - 1) + ")"; //Send the r instruction to the engine. - engine.voidEval(rexp); + engine.voidEval(String.format(setNamesString, this.variable, + namesString)); } else { //if size is not correct, throw a IndexOutOfBoundsException. - throw new IndexOutOfBoundsException( - "Cannot assign the names attribute, the names List is too long.\nThe size of names (" + - names.size() + - ") must be shorter or equal to the data.frame length(" + - data.size() + ")."); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + names.size(), data.size())); } } @@ -235,23 +252,21 @@ * @throws IndexOutOfBoundsException * when the index is out of the data.frame bounds. */ - public void setName(int x, String name) throws RException, - IndexOutOfBoundsException { + public void setName(int x, String name) throws RException { //check if the index is valid if (x < names.size()) { names.set(x, name); //create the r instruction (names(var)[x]<-"name") - String rexp = "names(" + this.variable + ")[" + (x + 1) + "]<-\"" + - name + "\""; + String rexp = String.format(setNameString, this.variable, x + 1, + name); //Send the R instruction to the engine. engine.voidEval(rexp); } else { - //if index is out of bounds, throw a IndexOutOfBOundsException - throw new IndexOutOfBoundsException( - "Cannot assign the name, the index is out of bounds.\nIndex :" + - x + "; data.frame size : " + data.size() + "."); + //if index is out of bounds, throw a IndexOutOfBoundsException + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, data.size())); } } @@ -266,12 +281,11 @@ * when the row.names size get from R is bigger than the local * data size. */ - public List<String> getRowNames() throws RException, - IndexOutOfBoundsException { + public List<String> getRowNames() throws RException { if (engine.isAutoCommit()) { //Get back the names from R. - String[] rowNamesArray = (String[]) engine.eval("row.names(" + - this.variable + ")"); + String[] rowNamesArray = (String[]) engine.eval(String.format( + getRowNamesString, this.variable)); //Check if size is correct, if yes, modify local data. if (rowNamesArray.length <= this.data.get(0).size()) { @@ -282,11 +296,9 @@ return rowNames; } else { //if size is not correct, throw a RException. - throw new IndexOutOfBoundsException( - "Data inconsistency, local data is smaller (size : " + this.data.get(0). - size() + ") than the names ArrayList in R (size : " + - rowNamesArray.length + - ").\nYou may want to force an update"); + throw new IndexOutOfBoundsException(String.format( + dataInconsistencyText, rowNamesArray.length, this.data. + get(0))); } } else { return this.rowNames; @@ -307,11 +319,11 @@ */ public String getRowName(int y) throws RException { //check if the index is valid - if (y < names.size()) { + if (y < rowNames.size()) { if (engine.isAutoCommit()) { //Get back the names from R. - String name = (String) engine.eval( - "row.names(" + this.variable + ")[" + (y + 1) + "]"); + String name = (String) engine.eval(String.format( + getRowNameString, this.variable, y + 1)); //Check if the String is returned. if ((name != null) && (!name.equals(""))) { @@ -320,7 +332,8 @@ } } else { //if String is not returned, throw an IndexOutOfBOundsException. - throw new IndexOutOfBoundsException("Your index is not valid"); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + y, rowNames.size())); } return this.rowNames.get(y); @@ -339,29 +352,29 @@ * when the row names ArrayList is longer than the data.frame * length */ - public void setRowNames(List<String> rowNames) throws RException, - IndexOutOfBoundsException { + public void setRowNames(List<String> rowNames) throws RException { //Check if the size is correct, if yes, do the modifications and send them to R. if (rowNames.size() == data.get(0).size()) { this.rowNames = rowNames; //Create the r instruction (row.names(var)<-c("name 1",...,"name x")). - String rexp = "row.names(" + this.variable + ")<-c("; + String rowNamesString = ""; for (int i = 0; i < this.rowNames.size(); i++) { - rexp += "\"" + rowNames.get(i) + "\","; + if (i != 0) { + rowNamesString += ","; + } + rowNamesString += "\"" + rowNames.get(i) + "\""; } - rexp = rexp.substring(0, rexp.length() - 1) + ")"; + String rexp = String.format(setRowNamesString, this.variable, + rowNamesString); //Send the r instruction to the engine. engine.voidEval(rexp); } else { //if size is not correct, throw a RException. - throw new IndexOutOfBoundsException( - "Cannot assign the names attribute, the ArrayList is too long.\nThe size of names (" + - rowNames.size() + - ") must be shorter or equal to the data.frame length(" + data.get(0). - size() + ")."); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + rowNames.size(), data.get(0).size())); } } @@ -377,23 +390,21 @@ * @throws IndexOutOfBoundsException * when the index is out of the data.frame bounds. */ - public void setRowName(int x, String rowName) throws RException, - IndexOutOfBoundsException { + public void setRowName(int x, String rowName) throws RException { //check if the index is valid if (x < rowNames.size()) { rowNames.set(x, rowName); //create the r instruction (row.names(var)[x]<-"rowName") - String rexp = "row.names(" + this.variable + ")[" + (x + 1) + - "]<-\"" + rowName + "\""; + String rexp = String.format(setRowNameString, this.variable, x + 1, + rowName); //Send the R instruction to the engine. engine.voidEval(rexp); } else { //if index is out of bounds, throw a RException - throw new IndexOutOfBoundsException( - "Cannot assign the name, the index is out of bounds.\nIndex :" + - x + "; data.frame size : " + data.size() + "."); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, data.size())); } } @@ -436,8 +447,7 @@ @Override public String toRString() throws RException { if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot instantiate data.frame in R, no variable name given"); + throw new RException(noVariable); } String returnString = this.variable + "<-data.frame("; if (!(this.data.isEmpty())) { @@ -509,20 +519,18 @@ * @throws ArrayStoreException * if the target destination cannot accept double value */ - public void set(int x, int y, double data) throws RException, - IndexOutOfBoundsException, ArrayStoreException { + public void set(int x, int y, double data) throws RException { if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); + throw new RException(noVariable); } if (x >= this.data.size()) { - throw new IndexOutOfBoundsException("The x value is too high : " + x + - ">=" + this.data.size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, this.data.size())); } if (y >= this.data.get(0).size()) { - throw new IndexOutOfBoundsException("The y value is too high : " + y + - ">=" + this.data.get(0).size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + y, this.data.get(0).size())); } if (this.data.get(x).get(y) instanceof Double) { ((ArrayList<Double>) this.data.get(x)).set(y, data); @@ -553,16 +561,15 @@ */ public void set(int x, int y, Boolean data) throws RException { if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); + throw new RException(noVariable); } if (x >= this.data.size()) { - throw new IndexOutOfBoundsException("The x value is too high : " + x + - ">=" + this.data.size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, this.data.size())); } if (y >= this.data.get(0).size()) { - throw new IndexOutOfBoundsException("The y value is too high : " + y + - ">=" + this.data.get(0).size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + y, this.data.get(0).size())); } if (this.data.get(x).get(y) instanceof Boolean) { ((ArrayList<Boolean>) this.data.get(x)).set(y, data); @@ -598,16 +605,15 @@ */ public void set(int x, int y, String data) throws RException { if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); + throw new RException(noVariable); } if (x >= this.data.size()) { - throw new IndexOutOfBoundsException("The x value is too high : " + x + - ">=" + this.data.size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, this.data.size())); } if (y >= this.data.get(0).size()) { - throw new IndexOutOfBoundsException("The y value is too high : " + y + - ">=" + this.data.get(0).size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + y, this.data.get(0).size())); } if (this.data.get(x).get(y) instanceof String) { ((ArrayList<String>) this.data.get(x)).set(y, data); @@ -637,16 +643,15 @@ */ public void set(int x, int y, int data) throws RException { if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); + throw new RException(noVariable); } if (x >= this.data.size()) { - throw new IndexOutOfBoundsException("The x value is too high : " + x + - ">=" + this.data.size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, this.data.size())); } if (y >= this.data.get(0).size()) { - throw new IndexOutOfBoundsException("The y value is too high : " + y + - ">=" + this.data.get(0).size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + y, this.data.size())); } if (this.data.get(x).get(y) instanceof Integer) { ((ArrayList<Integer>) this.data.get(x)).set(y, data); @@ -675,12 +680,12 @@ public Object get(int x, int y) throws RException, IndexOutOfBoundsException { if (x >= this.data.size()) { - throw new IndexOutOfBoundsException("The x value is too high : " + x + - ">=" + this.data.size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, this.data.size())); } if (y >= this.data.get(0).size()) { - throw new IndexOutOfBoundsException("The y value is too high : " + y + - ">=" + this.data.get(0).size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + y, this.data.get(0).size())); } if (engine.isAutoCommit()) { Object returnObject = engine.eval(this.variable + "[" + (y + 1) + @@ -703,26 +708,6 @@ } /** - * Method to set the data.frame variable name - * - * @param variable - * the new variable name - * @throws RException - * if something wrong happen while assigning the data.frame to - * the new variable in R. - */ - public void setVariable(String variable) throws RException { - this.variable = variable; - try { - engine.voidEval(toRString()); - } catch (RException eee) { - throw new RException( - "An error occured while trying to assign the data.frame in R", - eee); - } - } - - /** * Method to get the ArrayLists of the R data.frame (there is no * synchronizing with R, use the update() method to synchronize data with R * before using this method if you think data may have changed. @@ -784,15 +769,15 @@ } //update row names - String[] rowNamesArray = (String[]) engine.eval("row.names(" + - this.variable + ")"); + String[] rowNamesArray = (String[]) engine.eval(String.format( + getRowNamesString, this.variable)); for (int i = 0; i < rowNamesArray.length; i++) { rowNames.add(rowNamesArray[i]); } //update names - String[] namesArray = (String[]) engine.eval("names(" + - this.variable + ")"); + String[] namesArray = (String[]) engine.eval(String.format( + getNamesString, this.variable)); for (int i = 0; i < namesArray.length; i++) { names.add(namesArray[i]); } @@ -853,7 +838,7 @@ } file.close(); } catch (Exception e) { - e.printStackTrace(); + log.error(e); } } @@ -871,62 +856,10 @@ * Does the csv file contain names of the columns. */ public void importCsv(File inputFile, boolean rowNames, boolean names) { - String tmp; - Integer dataSize = 0; - try { + List<Object> tmp = new ArrayList<Object>(); + tmp.add("string"); + importCsv(inputFile, rowNames, names, (List) tmp); - BufferedReader first = new BufferedReader(new FileReader(inputFile)); - tmp = first.readLine(); - String[] splitted = tmp.split("\\;"); - if (rowNames) { - dataSize = splitted.length - 1; - } else { - dataSize = splitted.length; - } - - BufferedReader br = new BufferedReader(new FileReader(inputFile)); - if (this.data != null) { - this.data.clear(); - } - if ((rowNames) && (this.rowNames != null)) { - this.rowNames.clear(); - } - if (names) { - if (this.names != null) { - this.names.clear(); - } - tmp = br.readLine(); - splitted = tmp.split("\\;"); - for (int i = 1; i < splitted.length; i++) { - this.names.add(splitted[i]); - } - } - - List<List<? extends Object>> tempData = - new ArrayList<List<? extends Object>>(); - - for (int i = 0; i < dataSize; i++) { - List<Object> column = new ArrayList<Object>(); - tempData.add(column); - } - - while ((tmp = br.readLine()) != null) { - splitted = tmp.split("\\;"); - int index = 0; - if (rowNames) { - this.rowNames.add(splitted[0]); - index = 1; - } - for (int i = 0 + index; i < splitted.length; i++) { - ((ArrayList<Object>) tempData.get(i - index)).add( - (Object) splitted[i]); - } - } - br.close(); - this.data = tempData; - } catch (Exception e) { - e.printStackTrace(); - } } /** @@ -946,70 +879,17 @@ */ public void importCsv(File inputFile, boolean rowNames, boolean names, Object importType) { - String tmp; - Integer dataSize = 0; - try { - - BufferedReader first = new BufferedReader(new FileReader(inputFile)); - tmp = first.readLine(); - String[] splitted = tmp.split("\\;"); - if (rowNames) { - dataSize = splitted.length - 1; - } else { - dataSize = splitted.length; - } - - BufferedReader br = new BufferedReader(new FileReader(inputFile)); - if (this.data != null) { - this.data.clear(); - } - if ((rowNames) && (this.rowNames != null)) { - this.rowNames.clear(); - - } - if (names) { - if (this.names != null) { - this.names.clear(); - } - tmp = br.readLine(); - splitted = tmp.split("\\;"); - for (int i = 1; i < splitted.length; i++) { - this.names.add(splitted[i]); - } - } - - List<List<? extends Object>> tempData = - new ArrayList<List<? extends Object>>(); - - for (int i = 0; i < dataSize; i++) { - List<Object> column = new ArrayList<Object>(); - tempData.add(column); - } - - while ((tmp = br.readLine()) != null) { - splitted = tmp.split("\\;"); - int index = 0; - if (rowNames) { - this.rowNames.add(splitted[0]); - index = 1; - } - for (int i = 0 + index; i < splitted.length; i++) { - if (importType instanceof String) { - ((ArrayList<Object>) tempData.get(i - index)).add( - (Object) splitted[i]); - } else if (importType instanceof Double) { - ((ArrayList<Object>) tempData.get(i - index)).add(Double. - valueOf(splitted[i])); - } else if (importType instanceof Integer) { - ((ArrayList<Object>) tempData.get(i - index)).add(Integer. - valueOf(splitted[i])); - } - } - } - br.close(); - this.data = tempData; - } catch (Exception e) { - e.printStackTrace(); + List<Object> tmp = new ArrayList<Object>(); + if (importType instanceof String) { + log.info("string"); + tmp.add((String) importType); + importCsv(inputFile, rowNames, names, (List) tmp); + } else if (importType instanceof Double) { + tmp.add((Double) importType); + importCsv(inputFile, rowNames, names, tmp); + } else if (importType instanceof Integer) { + tmp.add((Integer) importType); + importCsv(inputFile, rowNames, names, tmp); } } @@ -1035,10 +915,7 @@ String tmp; Integer dataSize = 0; try { - - BufferedReader first = new BufferedReader(new FileReader(inputFile)); - tmp = first.readLine(); - String[] splitted = tmp.split("\\;"); + String[] splitted = getLines(inputFile); if (rowNames) { dataSize = splitted.length - 1; } else { @@ -1080,7 +957,21 @@ index = 1; } for (int i = 0 + index; i < splitted.length; i++) { - if (importTypes.get(i - index) instanceof String) { + //test the size of the inputType list. If 1 import all the + //columns as the type of the first + if (importTypes.size() == 1) { + if (importTypes.get(0) instanceof String) { + ((ArrayList<Object>) tempData.get(i - index)).add( + (Serializable) splitted[i]); + } else if (importTypes.get(0) instanceof Double) { + ((ArrayList<Object>) tempData.get(i - index)).add(Double. + valueOf(splitted[i])); + } else if (importTypes.get(0) instanceof Integer) { + ((ArrayList<Object>) tempData.get(i - index)).add(Integer. + valueOf(splitted[i])); + } + + } else if (importTypes.get(i - index) instanceof String) { ((ArrayList<Object>) tempData.get(i - index)).add( (Serializable) splitted[i]); } else if (importTypes.get(i - index) instanceof Double) { @@ -1095,7 +986,16 @@ br.close(); this.data = tempData; } catch (Exception e) { - e.printStackTrace(); + log.error(e); } } + + private String[] getLines(File inputFile) throws IOException, + FileNotFoundException { + String tmp; + BufferedReader first = new BufferedReader(new FileReader(inputFile)); + tmp = first.readLine(); + String[] splitted = tmp.split("\\;"); + return splitted; + } } Modified: trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java 2009-07-26 17:11:04 UTC (rev 115) +++ trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java 2009-07-30 14:05:04 UTC (rev 116) @@ -221,4 +221,24 @@ public String getVariable() { return this.variable; } + + /** + * Method to set the list variable name + * + * @param variable + * the new variable name + * @throws RException + * if something wrong happen while assigning the list to the new + * variable in R. + */ + public void setVariable(String variable) throws RException { + this.variable = variable; + try { + engine.voidEval(toRString()); + } catch (RException eee) { + throw new RException( + "An error occured while trying to assign the list in R", + eee); + } + } } Modified: trunk/src/main/java/org/nuiton/j2r/types/RList.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/RList.java 2009-07-26 17:11:04 UTC (rev 115) +++ trunk/src/main/java/org/nuiton/j2r/types/RList.java 2009-07-30 14:05:04 UTC (rev 116) @@ -30,6 +30,15 @@ private Log log = LogFactory.getLog(RList.class); private List<String> names; private List<Object> data; + private String setNamesString = "names(%s)<-c(%s)"; + private String setNameString = "names(%s)[%s]<-\"%s\""; + private String getNamesString = "names(%s)"; + private String getNameString = "names(%s)[%s]"; + private String indexExceptionText = + "Cannot perform operation, index is superior to size.\nIndex : %s\nSize : %s"; + private String dataInconsistencyText = + "There is an inconsistency between the local and distant data.\nLocal data size : %s\nDistant data size : %s"; + private String noVariable = "No variable name given"; public RList(REngine engine) { super(); @@ -62,16 +71,13 @@ * the R list * @throws RException * if an error occurs while getting back the names from R. - * @throws IndexOutOfBoundsException - * when the row.names size get from R is bigger than the local - * data size. */ - public List<String> getNames() throws RException, IndexOutOfBoundsException { + public List<String> getNames() throws RException { if (engine.isAutoCommit()) { //Get back the names from R. - String[] namesArray = (String[]) engine.eval("names(" + - this.variable + ")"); + String[] namesArray = (String[]) engine.eval(String.format( + getNamesString, this.variable)); //Check if size is correct, if yes, modify local data. if (namesArray.length <= this.data.size()) { @@ -82,10 +88,9 @@ return names; } else { //if size is not correct, throw a RException. - throw new IndexOutOfBoundsException( - "Data inconsistency, local data is smaller (size : " + - this.data.size() + ") than the names in R (size : " + - namesArray.length + ")"); + throw new IndexOutOfBoundsException(String.format( + dataInconsistencyText, this.data.size(), + namesArray.length)); } } else { return this.names; @@ -104,18 +109,15 @@ * * @throws RException * if an error occurs while getting back the name from R. - * - * @throws IndexOutOfBoundsException - * if the x index is out of bounds. */ - public String getName(int x) throws RException, IndexOutOfBoundsException { + public String getName(int x) throws RException { //check if the index is valid if (x < names.size()) { if (engine.isAutoCommit()) { //Get back the names from R. - String name = (String) engine.eval("names(" + this.variable + - ")[" + (x + 1) + "]"); + String name = (String) engine.eval(String.format(getNameString, + this.variable, x + 1)); //Check if the String is returned. if ((name != null) && (!name.equals(""))) { @@ -124,8 +126,8 @@ } } else { //if String is not returned, throw an IndexOutOfBOundsException. - throw new IndexOutOfBoundsException("Your index " + x + - " is not valid"); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, names.size())); } return this.names.get(x); @@ -140,29 +142,29 @@ * @throws RException * when the names list is longer than the list length. */ - public void setNames(List<String> names) throws RException, - IndexOutOfBoundsException { + public void setNames(List<String> names) throws RException { //Check if the size is correct, if yes, do the modifications and send them to R. if (names.size() <= data.size()) { this.names = names; //Create the r instruction (names(var)<-c("name 1",...,"name x")). - String rexp = "names(" + this.variable + ")<-c("; + String namesString = ""; for (int i = 0; i < this.names.size(); i++) { - rexp += "\"" + names.get(i) + "\","; + if (i != 0) { + namesString += ","; + } + namesString += "\"" + names.get(i) + "\""; } - rexp = rexp.substring(0, rexp.length() - 1) + ")"; + String rexp = String.format(setNamesString, this.variable, + namesString); //Send the r instruction to the engine. engine.voidEval(rexp); } else { //if size is not correct, throw a IndexOutOfBoundsException. - throw new IndexOutOfBoundsException( - "Cannot assign the names attribute, the names List is too long.\nThe size of names (" + - names.size() + - ") must be shorter or equal to the list length(" + - data.size() + ")."); + throw new IndexOutOfBoundsException(String.format( + dataInconsistencyText, names.size(), data.size())); } } @@ -175,11 +177,8 @@ * Name of the object. * @throws RException * if an error occur while in R - * @throws IndexOutOfBoundsException - * when the index is out of the list bounds. */ - public void setName(int x, String name) throws RException, - IndexOutOfBoundsException { + public void setName(int x, String name) throws RException { //check if the index is valid if (x < data.size()) { for (int i = 0; i <= x; i++) { @@ -199,16 +198,15 @@ } //create the r instruction (names(var)[x]<-"name") - String rexp = "names(" + this.variable + ")[" + (x + 1) + "]<-\"" + - name + "\""; + String rexp = String.format(setNameString, this.variable, x + 1, + name); //Send the R instruction to the engine. engine.voidEval(rexp); } else { //if index is out of bounds, throw a IndexOutOfBOundsException - throw new IndexOutOfBoundsException( - "Cannot assign the name, the index is out of bounds.\nIndex :" + - x + "; data.frame size : " + data.size() + "."); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, data.size())); } } @@ -242,26 +240,6 @@ } /** - * Method to set the list variable name - * - * @param variable - * the new variable name - * @throws RException - * if something wrong happen while assigning the list to the new - * variable in R. - */ - public void setVariable(String variable) throws RException { - this.variable = variable; - try { - engine.voidEval(toRString()); - } catch (RException eee) { - throw new RException( - "An error occured while trying to assign the list in R", - eee); - } - } - - /** * Method to export the list in a String for evaluation in R. * * @return a R string representation of the list to create it in R. @@ -270,10 +248,7 @@ */ @Override public String toRString() throws RException { - if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot instantiate data.frame in R, no variable name given"); - } + testVariable(); String returnString = this.variable + "<-list("; if ((this.data != null) && (!(this.data.isEmpty()))) { @@ -317,10 +292,7 @@ * if no variable name has been given to the list */ public void set(int x, double data) throws RException { - if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); - } + testVariable(); for (int i = 0; i <= x; i++) { try { this.data.get(i); @@ -350,10 +322,7 @@ * if no variable name has been given to the list */ public void set(int x, Boolean data) throws RException { - if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); - } + testVariable(); for (int i = 0; i <= x; i++) { try { this.data.get(i); @@ -385,15 +354,9 @@ * value to set * @throws RException * if no variable name has been given to the list - * @throws IndexOutOfBoundsException - * if the x coordinate is not correct. */ - public void set(int x, String data) throws RException, - IndexOutOfBoundsException { - if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); - } + public void set(int x, String data) throws RException { + testVariable(); for (int i = 0; i <= x; i++) { try { this.data.get(i); @@ -421,14 +384,9 @@ * value to set * @throws RException * if no variable name has been given to the list - * @throws IndexOutOfBoundsException - * if the x coordinate is not correct. */ public void set(int x, int data) throws RException { - if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); - } + testVariable(); for (int i = 0; i <= x; i++) { try { this.data.get(i); @@ -459,10 +417,7 @@ * if no variable name has been given to the list */ public void set(int x, REXP data) throws RException { - if ((this.variable.equals("")) || (this.variable == null)) { - throw new RException( - "Cannot propage modification in R, no variable name given"); - } + testVariable(); for (int i = 0; i <= x; i++) { try { this.data.get(i); @@ -491,13 +446,11 @@ * @return the Object located at the [x] coordinate * @throws RException * if no variable name has been given to the list - * @throws IndexOutOfBoundsException - * if the xcoordinate is not correct. */ - public Object get(int x) throws RException, IndexOutOfBoundsException { + public Object get(int x) throws RException { if (x >= this.data.size()) { - throw new IndexOutOfBoundsException("The x value is too high : " + x + - ">=" + this.data.size()); + throw new IndexOutOfBoundsException(String.format(indexExceptionText, + x, this.data.size())); } if (engine.isAutoCommit()) { Object returnObject = engine.eval(this.variable + "[[" + (x + 1) + @@ -566,8 +519,8 @@ } //update names - String[] namesArray = (String[]) engine.eval("names(" + this.variable + - ")"); + String[] namesArray = (String[]) engine.eval(String.format( + getNamesString, this.variable)); for (int i = 0; i < namesArray.length; i++) { names.add(namesArray[i]); } @@ -591,4 +544,11 @@ attributes.put(key, attribute); } } + + public void testVariable() throws RException { + if ((this.variable.equals("")) || (this.variable == null)) { + throw new RException( + noVariable); + } + } }