Author: jcouteau Date: 2009-07-31 16:27:55 +0200 (Fri, 31 Jul 2009) New Revision: 118 Modified: trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java Log: Refactor and add some comments Modified: trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java 2009-07-31 09:18:50 UTC (rev 117) +++ trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java 2009-07-31 14:27:55 UTC (rev 118) @@ -41,8 +41,14 @@ //Engine used for R instructions. protected REngine engine; + //R instruction to assign one attribute value. + private String assignAttribute = "attr(%s,\"%s\")<-%s"; + + //R instruction to get one attribute value. + private String getAttribute = "attr(%s,\"%s\")"; + /** - * Always need to be implemented by extending classes + * Always need to be implemented by extending classes. * @return null * @throws org.nuiton.j2r.RException */ @@ -60,91 +66,110 @@ public void getFrom(String variable) throws RException { } + /** {@inheritDoc} */ @Override public void setAttributes(Map<String, Object> attributes) throws RException { + //TODO should be useful to test the validity of attributes before + //assigning it. this.attributes = attributes; - if ((this.attributes != null) && (!this.attributes.isEmpty())) { Set<String> keyset = attributes.keySet(); String[] keys = keyset.toArray(new String[0]); for (int i = 0; i < keys.length; i++) { + //foreach type of attribute, adapt the R instruction. if (this.attributes.get(keys[i]) instanceof String) { - engine.eval("attr(" + this.variable + ",\"" + keys[i] + - "\")<-\"" + this.attributes.get(keys[i]) + "\""); + engine.eval(String.format(assignAttribute, this.variable, + keys[i], "\"" + this.attributes.get(keys[i]) + "\"")); + //String, value between quotes } else if (this.attributes.get(keys[i]) instanceof Double) { - engine.eval("attr(" + this.variable + ",\"" + keys[i] + - "\")<-" + this.attributes.get(keys[i]) + ""); + engine.eval(String.format(assignAttribute, this.variable, + keys[i], this.attributes.get(keys[i]))); } else if (this.attributes.get(keys[i]) instanceof Integer) { - engine.eval("attr(" + this.variable + ",\"" + keys[i] + - "\")<-as.integer(" + this.attributes.get(keys[i]) + - ")"); + engine.eval(String.format(assignAttribute, this.variable, + keys[i], "as.integer(" + + this.attributes.get(keys[i]) + ")")); + //Integer, value formated by the R function : as.integer() } else if (this.attributes.get(keys[i]) instanceof Boolean) { if ((Boolean) this.attributes.get(keys[i])) { - engine.eval("attr(" + this.variable + ",\"" + keys[i] + - "\")<-TRUE"); + engine.eval(String.format(assignAttribute, this.variable, + keys[i], "TRUE")); + //Boolean true replaced by TRUE } else { - engine.eval("attr(" + this.variable + ",\"" + keys[i] + - "\")<-FALSE"); + engine.eval(String.format(assignAttribute, this.variable, + keys[i], "FALSE")); + //Boolean false replaced by REPLACE } } else if (this.attributes.get(keys[i]) instanceof REXP) { - engine.eval("attr(" + this.variable + ",\"" + keys[i] + - "\")<-" + ((REXP) this.attributes.get(keys[i])). - toRString()); + engine.eval(String.format(assignAttribute, this.variable, + keys[i], ((REXP) this.attributes.get(keys[i])). + toRString())); + //REXP replaced by the result of their toRString() method. } else { - log.warn("This attribute is not valid : " + keys[i] + " ; " + - this.attributes.get(keys[i]) + - ". It will not be sent to R"); + if (log.isWarnEnabled()) { + log.warn("This attribute is not valid : " + keys[i] + + " ; " + this.attributes.get(keys[i]) + + ". It will not be sent to R"); + //if the attribute is not recognised. + } } } } } + /** {@inheritDoc} */ @Override public Map<String, Object> getAttributes() throws RException { if (engine.isAutoCommit()) { + //get the number of attributes Integer attributeslength = (Integer) engine.eval( "length(attributes(" + this.variable + "))"); for (int i = 0; i < attributeslength; i++) { + //Get the name of the i attribute String key = (String) engine.eval("names(attributes(" + this.variable + "))[" + (i + 1) + "]"); - Object newAttribute = engine.eval( - "attributes(" + this.variable + ")$" + key); - if (attributes.containsKey(key)) { - attributes.remove(key); - attributes.put(key, newAttribute); - } else { - attributes.put(key, newAttribute); - } + //Get the attribute + getAttribute(key); } } return this.attributes; } + /** {@inheritDoc} */ @Override public Object getAttribute(String attribute) throws RException { if (engine.isAutoCommit()) { Object returnedAttribute; - if ((Boolean) engine.eval("is.data.frame(attr(" + this.variable + - ",\"" + attribute + "\"))")) { + //test if the attribute is a data.frame + if ((Boolean) engine.eval("is.data.frame(" + String.format( + getAttribute, this.variable, attribute) + ")")) { + //if attribute is a list, import the data.frame from R returnedAttribute = new RDataFrame(engine); - ((RDataFrame) returnedAttribute).getFrom("attr(" + this.variable + - ",\"" + attribute + "\")"); - } else if ((Boolean) engine.eval("is.list(attr(" + this.variable + - ",\"" + attribute + "\"))")) { + ((RDataFrame) returnedAttribute).getFrom(String.format( + getAttribute, this.variable, attribute)); + //test if the attribute is a list + } else if ((Boolean) engine.eval("is.list(" + String.format( + getAttribute, this.variable, attribute) + ")")) { + + //if attribute is a list, import it from R. returnedAttribute = new RList(engine); - ((RList) returnedAttribute).getFrom("attr(" + this.variable + - ",\"" + attribute + "\")"); + ((RList) returnedAttribute).getFrom(String.format(getAttribute, + this.variable, attribute)); } else { - returnedAttribute = engine.eval( - "attr(" + this.variable + ",\"" + attribute + "\")"); + //else attribute is imported as any other R expression. + returnedAttribute = engine.eval(String.format(getAttribute, + this.variable, attribute)); } + //put the attribute in the attribute list if (returnedAttribute != null) { if (attributes.containsKey(attribute)) { + //if the attribute already exists, remove it first (or you + //will have too times the same attribubte with different + //values) attributes.remove(attribute); attributes.put(attribute, returnedAttribute); } else { @@ -154,82 +179,76 @@ throw new RException("Attribute does not exist"); } } else if (!attributes.containsKey(attribute)) { + //if no autocommit and attribute does not exist throw new RException("Attribute does not exist"); } return attributes.get(attribute); } + /** {@inheritDoc} */ @Override public void setAttribute(String attribute, Object value) throws RException { + //variable to check if the attribute is valid before setting it. + boolean isOK = false; if (value instanceof String) { - if (attributes.containsKey(attribute)) { - attributes.remove(attribute); - attributes.put(attribute, value); - } else { - attributes.put(attribute, value); - } - engine.voidEval("attr(" + this.variable + ",\"" + attribute + - "\")<-\"" + value + "\""); + isOK = true; + engine.voidEval(String.format(assignAttribute, this.variable, + attribute, "\"" + value + "\"")); + //if String, between quotes } else if (value instanceof Double) { - if (attributes.containsKey(attribute)) { - attributes.remove(attribute); - attributes.put(attribute, value); - } else { - attributes.put(attribute, value); - } - engine.voidEval("attr(" + this.variable + ",\"" + attribute + - "\")<-" + value); + isOK = true; + engine.voidEval(String.format(assignAttribute, this.variable, + attribute, value)); } else if (value instanceof Integer) { - if (attributes.containsKey(attribute)) { - attributes.remove(attribute); - attributes.put(attribute, value); - } else { - attributes.put(attribute, value); - } - engine.voidEval("attr(" + this.variable + ",\"" + attribute + - "\")<-as.integer(" + value + ")"); + isOK = true; + engine.voidEval(String.format(assignAttribute, this.variable, + attribute, "as.integer(" + value + ")")); + //If integer in the R function : as.integer() } else if (value instanceof Boolean) { - if (attributes.containsKey(attribute)) { - attributes.remove(attribute); - attributes.put(attribute, value); - } else { - attributes.put(attribute, value); - } + isOK = true; if ((Boolean) value) { - engine.voidEval("attr(" + this.variable + ",\"" + attribute + - "\")<-TRUE"); + engine.voidEval(String.format(assignAttribute, this.variable, + attribute, "TRUE")); + //If boolean true, replaced by TRUE } else { - engine.voidEval("attr(" + this.variable + ",\"" + attribute + - "\")<-FALSE"); + engine.voidEval(String.format(assignAttribute, this.variable, + attribute, "FALSE")); + //If boolean false, replaced by FALSE } } else if (value instanceof REXP) { + isOK = true; + engine.voidEval(String.format(assignAttribute, this.variable, + attribute, ((REXP) value).toRString())); + //if REXP, use its method toRString() + } else { + log.warn("This attribute is not valid : " + attribute + " ; " + + value + ". It will not be processed"); + } + //if attribute is valid, out it in the attribute list. + if (isOK) { if (attributes.containsKey(attribute)) { attributes.remove(attribute); attributes.put(attribute, value); } else { attributes.put(attribute, value); } - engine.voidEval("attr(" + this.variable + ",\"" + attribute + - "\")<-" + ((REXP) value).toRString()); - } else { - log.warn("This attribute is not valid : " + attribute + " ; " + - value + ". It will not be processed"); } } + /** {@inheritDoc} */ @Override public String getVariable() { return this.variable; } - /** - * Method to set the list variable name + /** + * Method to set the R expression variable name * * @param variable * the new variable name * @throws RException - * if something wrong happen while assigning the list to the new - * variable in R. + * if something wrong happen while assigning the R expression to + * the new variable in R. */ public void setVariable(String variable) throws RException { this.variable = variable;