From 2b8b874261ac84e5ac1f92cacb9cbe4a03854854 Mon Sep 17 00:00:00 2001 From: Dimagi Date: Thu, 22 Jun 2017 11:57:58 +0530 Subject: [PATCH 1/4] Add xpath function checksum --- .../org/commcare/cases/util/StringUtils.java | 21 +++- .../javarosa/core/util/ArrayUtilities.java | 16 ++++ .../xpath/expr/XPathChecksumFunc.java | 96 +++++++++++++++++++ .../xpath/parser/ast/ASTNodeFunctionCall.java | 2 + .../javarosa/xpath/test/XPathEvalTest.java | 36 +++---- 5 files changed, 152 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/javarosa/xpath/expr/XPathChecksumFunc.java diff --git a/src/main/java/org/commcare/cases/util/StringUtils.java b/src/main/java/org/commcare/cases/util/StringUtils.java index 3e30674918..8d15820f75 100644 --- a/src/main/java/org/commcare/cases/util/StringUtils.java +++ b/src/main/java/org/commcare/cases/util/StringUtils.java @@ -1,6 +1,7 @@ package org.commcare.cases.util; import org.commcare.modern.util.Pair; +import org.javarosa.core.util.ArrayUtilities; import java.text.Normalizer; import java.util.regex.Pattern; @@ -45,9 +46,9 @@ public synchronized static String normalize(String input) { //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { normalized = Normalizer.normalize(input, Normalizer.Form.NFD); //} else { - //TODO: I doubt it's worth it, but in theory we could run - //some other normalization for the minority of pre-API9 - //devices. + //TODO: I doubt it's worth it, but in theory we could run + //some other normalization for the minority of pre-API9 + //devices. //} String output = diacritics.matcher(normalized).replaceAll("").toLowerCase(); @@ -134,4 +135,18 @@ private static int LevenshteinDistance(String s0, String s1) { // the distance is the cost for transforming all letters in both strings return cost[len0 - 1]; } + + /* + * Converts a string to a string array. + */ + public static String[] toArray(String str) { + + String[] myArray = new String[str.length()]; + + for (int i = 0; i < str.length(); i++) { + myArray[i] = str.substring(i, i + 1); + } + + return myArray; + } } diff --git a/src/main/java/org/javarosa/core/util/ArrayUtilities.java b/src/main/java/org/javarosa/core/util/ArrayUtilities.java index 8703dcd327..f1bcc205f3 100755 --- a/src/main/java/org/javarosa/core/util/ArrayUtilities.java +++ b/src/main/java/org/javarosa/core/util/ArrayUtilities.java @@ -1,5 +1,7 @@ package org.javarosa.core.util; +import java.lang.reflect.Array; +import java.util.Arrays; import java.util.Vector; /** @@ -32,6 +34,20 @@ public static boolean arraysEqual(byte[] array1, byte[] array2) { return true; } + /* + * Reverses an array + */ + public static T[] reverse(Object[] myArray, Class tClass) { + Object[] reversed = new Object[myArray.length]; + + for (int i = 0; i < myArray.length; i++) { + reversed[i] = myArray[myArray.length - (i + 1)]; + } + + return Arrays.copyOf(reversed, reversed.length, tClass); + } + + /** * Find a single intersecting element common to two lists, or null if none * exists. Note that no unique condition will be reported if there are multiple diff --git a/src/main/java/org/javarosa/xpath/expr/XPathChecksumFunc.java b/src/main/java/org/javarosa/xpath/expr/XPathChecksumFunc.java new file mode 100644 index 0000000000..c9010c70ad --- /dev/null +++ b/src/main/java/org/javarosa/xpath/expr/XPathChecksumFunc.java @@ -0,0 +1,96 @@ +package org.javarosa.xpath.expr; + +import org.commcare.cases.util.StringUtils; +import org.javarosa.core.model.condition.EvaluationContext; +import org.javarosa.core.model.instance.DataInstance; +import org.javarosa.core.util.ArrayUtilities; +import org.javarosa.xpath.XPathUnsupportedException; +import org.javarosa.xpath.parser.XPathSyntaxException; + +public class XPathChecksumFunc extends XPathFuncExpr { + public static final String NAME = "checksum"; + private static final int EXPECTED_ARG_COUNT = 2; + + public static final String ALGORITHM_KEY_VERHOEFF = "verhoeff"; + + public XPathChecksumFunc() { + name = NAME; + expectedArgCount = EXPECTED_ARG_COUNT; + } + + public XPathChecksumFunc(XPathExpression[] args) throws XPathSyntaxException { + super(NAME, args, EXPECTED_ARG_COUNT, true); + } + + @Override + public Object evalBody(DataInstance model, EvaluationContext evalContext, Object[] evaluatedArgs) { + return checksum(evaluatedArgs[0], evaluatedArgs[1]); + } + + /** + * @param o1 algorithm type used to calculate checksum. We only support 'verhoeff' for now. + * @param o2 input we are calculating checksum for + * @return checksum of {@code o2} calculated using {@code o1} type algorithm + */ + private String checksum(Object o1, Object o2) { + String algorithmKey = FunctionUtils.toString(o1); + String input = FunctionUtils.toString(o2); + + switch (algorithmKey) { + case ALGORITHM_KEY_VERHOEFF: + return verhoeffChecksum(input); + default: + throw new XPathUnsupportedException("Algorithm key " + algorithmKey + " is not supported for checksum"); + } + } + + /** + * Calculates Verhoeff checksum for the given {@code input} string

+ * + * @param input input string to calculate verhoeff checksum for + * @return Verhoeff checksum value for {@code input} + * @see Based on Verhoeff checksum implementation here + */ + private String verhoeffChecksum(String input) { + + // The multiplication table + int[][] op = new int[][]{ + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + {1, 2, 3, 4, 0, 6, 7, 8, 9, 5}, + {2, 3, 4, 0, 1, 7, 8, 9, 5, 6}, + {3, 4, 0, 1, 2, 8, 9, 5, 6, 7}, + {4, 0, 1, 2, 3, 9, 5, 6, 7, 8}, + {5, 9, 8, 7, 6, 0, 4, 3, 2, 1}, + {6, 5, 9, 8, 7, 1, 0, 4, 3, 2}, + {7, 6, 5, 9, 8, 2, 1, 0, 4, 3}, + {8, 7, 6, 5, 9, 3, 2, 1, 0, 4}, + {9, 8, 7, 6, 5, 4, 3, 2, 1, 0} + }; + + // The permutation table + int[][] p = new int[][]{ + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + {1, 5, 7, 6, 2, 8, 3, 0, 9, 4}, + {5, 8, 0, 3, 7, 9, 6, 1, 4, 2}, + {8, 9, 1, 6, 0, 4, 3, 5, 2, 7}, + {9, 4, 5, 3, 1, 2, 6, 8, 7, 0}, + {4, 2, 8, 6, 5, 7, 3, 9, 0, 1}, + {2, 7, 9, 3, 8, 0, 6, 4, 1, 5}, + {7, 0, 4, 6, 9, 1, 3, 2, 5, 8} + }; + + // The inverse table + int[] inv = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9}; + + int check = 0; + + String[] mArray = ArrayUtilities.reverse(StringUtils.toArray(input), String[].class); + + for (int i = 0; i < mArray.length; i++) { + check = op[check][p[((i + 1) % 8)][Integer.parseInt(mArray[i])]]; + } + + return Integer.toString(inv[check]); + } + +} diff --git a/src/main/java/org/javarosa/xpath/parser/ast/ASTNodeFunctionCall.java b/src/main/java/org/javarosa/xpath/parser/ast/ASTNodeFunctionCall.java index fb538b9def..b3a4f8378d 100755 --- a/src/main/java/org/javarosa/xpath/parser/ast/ASTNodeFunctionCall.java +++ b/src/main/java/org/javarosa/xpath/parser/ast/ASTNodeFunctionCall.java @@ -163,6 +163,8 @@ private static XPathFuncExpr buildFuncExpr(String name, XPathExpression[] args) return new XPathJoinChunkFunc(args); case "id-compress": return new XPathIdCompressFunc(args); + case "checksum": + return new XPathChecksumFunc(args); default: return new XPathCustomRuntimeFunc(name, args); } diff --git a/src/test/java/org/javarosa/xpath/test/XPathEvalTest.java b/src/test/java/org/javarosa/xpath/test/XPathEvalTest.java index a12a545188..5d53b2d2c2 100755 --- a/src/test/java/org/javarosa/xpath/test/XPathEvalTest.java +++ b/src/test/java/org/javarosa/xpath/test/XPathEvalTest.java @@ -58,8 +58,8 @@ private void testEval(String expr, FormInstance model, EvaluationContext ec, Obj if (exceptionExpected) { fail("Expected exception, expression : " + expr); } else if ((result instanceof Double && expected instanceof Double)) { - Double o = (Double)result; - Double t = (Double)expected; + Double o = (Double) result; + Double t = (Double) expected; if (Math.abs(o - t) > DOUBLE_TOLERANCE) { fail("Doubles outside of tolerance [" + o + "," + t + " ]"); } else if (Double.isNaN(o) && !Double.isNaN(t)) { @@ -87,7 +87,7 @@ private void assertExceptionExpected(boolean exceptionExpected, Object expected, } @Test - public void testTypeCoercion(){ + public void testTypeCoercion() { Object str = FunctionUtils.InferType("notadouble"); Assert.assertTrue("'notadouble' coerced to the wrong type, " + str.getClass().toString(), str instanceof String); @@ -523,6 +523,10 @@ public void doTests() { testEval("id-compress(0, 'CD','','ABCDE',1)", null, ec, new XPathException()); testEval("id-compress(0, 'CD','CD','ABCDE',1)", null, ec, new XPathException()); + testEval("checksum('verhoeff','41310785898')", null, null, "4"); + testEval("checksum('verhoeff','66671496237')", null, null, "3"); + testEval("checksum('verhoefffff','41310785898')", null, null, new XPathUnsupportedException()); + //Variables EvaluationContext varContext = getVariableContext(); testEval("$var_float_five", null, varContext, new Double(5.0)); @@ -625,24 +629,24 @@ public void testOverrideNow() { ec.addFunctionHandler(new IFunctionHandler() { @Override public String getName() { - return "now"; + return "now"; } @Override public Vector getPrototypes() { - Vector p = new Vector<>(); - p.addElement(new Class[0]); - return p; + Vector p = new Vector<>(); + p.addElement(new Class[0]); + return p; } @Override public boolean rawArgs() { - return false; + return false; } @Override public Object eval(Object[] args, EvaluationContext ec) { - return "pass"; + return "pass"; } }); @@ -674,12 +678,12 @@ private TreeReference inlinePositionArgs(TreeReference treeRef) { if (!(predicates.elementAt(0) instanceof XPathNumericLiteral)) { throw new IllegalArgumentException("only position [] predicates allowed"); } - double d = ((XPathNumericLiteral)predicates.elementAt(0)).d; - if (d != (double)((int)d)) { + double d = ((XPathNumericLiteral) predicates.elementAt(0)).d; + if (d != (double) ((int) d)) { throw new IllegalArgumentException("invalid position: " + d); } - int multiplicity = (int)d - 1; + int multiplicity = (int) d - 1; if (treeRef.getMultiplicity(i) != TreeReference.INDEX_UNBOUND) { throw new IllegalArgumentException("Cannot inline already qualified steps"); } @@ -765,7 +769,7 @@ public boolean rawArgs() { @Override public Object eval(Object[] args, EvaluationContext ec) { - return new Double(((Double)args[0]).doubleValue() + ((Double)args[1]).doubleValue()); + return new Double(((Double) args[0]).doubleValue() + ((Double) args[1]).doubleValue()); } }); @@ -925,7 +929,7 @@ public boolean rawArgs() { @Override public Object eval(Object[] args, EvaluationContext ec) { - return ((Boolean)args[0]).booleanValue() ? new CustomSubType() : new CustomType(); + return ((Boolean) args[0]).booleanValue() ? new CustomSubType() : new CustomType(); } }); @@ -978,7 +982,7 @@ private String printArgs(Object[] oa) { int lastIndex = Math.max(fullName.lastIndexOf('.'), fullName.lastIndexOf('$')); sb.append(fullName.substring(lastIndex + 1, fullName.length())); sb.append(":"); - sb.append(oa[i] instanceof Date ? DateUtils.formatDate((Date)oa[i], DateUtils.FORMAT_ISO8601) : oa[i].toString()); + sb.append(oa[i] instanceof Date ? DateUtils.formatDate((Date) oa[i], DateUtils.FORMAT_ISO8601) : oa[i].toString()); if (i < oa.length - 1) sb.append(","); } @@ -1055,7 +1059,7 @@ public Vector getPrototypes() { @Override public Object eval(Object[] args, EvaluationContext ec) { - val = (String)args[0]; + val = (String) args[0]; return Boolean.TRUE; } }; From 1c50df8482193256cd55c46e49c454c1ee4edebc Mon Sep 17 00:00:00 2001 From: Dimagi Date: Thu, 22 Jun 2017 12:03:05 +0530 Subject: [PATCH 2/4] Formats correctly --- src/main/java/org/commcare/cases/util/StringUtils.java | 4 ++-- src/main/java/org/javarosa/core/util/ArrayUtilities.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/commcare/cases/util/StringUtils.java b/src/main/java/org/commcare/cases/util/StringUtils.java index 8d15820f75..e0d15c560d 100644 --- a/src/main/java/org/commcare/cases/util/StringUtils.java +++ b/src/main/java/org/commcare/cases/util/StringUtils.java @@ -136,9 +136,9 @@ private static int LevenshteinDistance(String s0, String s1) { return cost[len0 - 1]; } - /* + /** * Converts a string to a string array. - */ + */ public static String[] toArray(String str) { String[] myArray = new String[str.length()]; diff --git a/src/main/java/org/javarosa/core/util/ArrayUtilities.java b/src/main/java/org/javarosa/core/util/ArrayUtilities.java index f1bcc205f3..bd1f8b0af9 100755 --- a/src/main/java/org/javarosa/core/util/ArrayUtilities.java +++ b/src/main/java/org/javarosa/core/util/ArrayUtilities.java @@ -34,9 +34,9 @@ public static boolean arraysEqual(byte[] array1, byte[] array2) { return true; } - /* - * Reverses an array - */ + /** + * Reverses an Array + */ public static T[] reverse(Object[] myArray, Class tClass) { Object[] reversed = new Object[myArray.length]; From a8dd5806cbe23eb10c286ed8ab867d75b4c8758a Mon Sep 17 00:00:00 2001 From: Dimagi Date: Fri, 23 Jun 2017 11:36:21 +0530 Subject: [PATCH 3/4] Add Checksum in funcList,revert casting formatting, Use ArrayList instead of array in checksum --- .../org/commcare/cases/util/StringUtils.java | 12 ++++++----- .../javarosa/core/util/ArrayUtilities.java | 16 -------------- .../javarosa/xpath/expr/FunctionUtils.java | 1 + .../xpath/expr/XPathChecksumFunc.java | 21 ++++++++++++------- .../javarosa/xpath/test/XPathEvalTest.java | 18 ++++++++-------- 5 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/commcare/cases/util/StringUtils.java b/src/main/java/org/commcare/cases/util/StringUtils.java index e0d15c560d..4b7f008e40 100644 --- a/src/main/java/org/commcare/cases/util/StringUtils.java +++ b/src/main/java/org/commcare/cases/util/StringUtils.java @@ -4,6 +4,8 @@ import org.javarosa.core.util.ArrayUtilities; import java.text.Normalizer; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Pattern; /** @@ -137,16 +139,16 @@ private static int LevenshteinDistance(String s0, String s1) { } /** - * Converts a string to a string array. + * Converts a string to a list of Characters. */ - public static String[] toArray(String str) { + public static ArrayList toList(String str) { - String[] myArray = new String[str.length()]; + ArrayList myArrayList = new ArrayList<>(str.length()); for (int i = 0; i < str.length(); i++) { - myArray[i] = str.substring(i, i + 1); + myArrayList.add(i, str.charAt(i)); } - return myArray; + return myArrayList; } } diff --git a/src/main/java/org/javarosa/core/util/ArrayUtilities.java b/src/main/java/org/javarosa/core/util/ArrayUtilities.java index bd1f8b0af9..8703dcd327 100755 --- a/src/main/java/org/javarosa/core/util/ArrayUtilities.java +++ b/src/main/java/org/javarosa/core/util/ArrayUtilities.java @@ -1,7 +1,5 @@ package org.javarosa.core.util; -import java.lang.reflect.Array; -import java.util.Arrays; import java.util.Vector; /** @@ -34,20 +32,6 @@ public static boolean arraysEqual(byte[] array1, byte[] array2) { return true; } - /** - * Reverses an Array - */ - public static T[] reverse(Object[] myArray, Class tClass) { - Object[] reversed = new Object[myArray.length]; - - for (int i = 0; i < myArray.length; i++) { - reversed[i] = myArray[myArray.length - (i + 1)]; - } - - return Arrays.copyOf(reversed, reversed.length, tClass); - } - - /** * Find a single intersecting element common to two lists, or null if none * exists. Note that no unique condition will be reported if there are multiple diff --git a/src/main/java/org/javarosa/xpath/expr/FunctionUtils.java b/src/main/java/org/javarosa/xpath/expr/FunctionUtils.java index fe24155d71..16899588a4 100644 --- a/src/main/java/org/javarosa/xpath/expr/FunctionUtils.java +++ b/src/main/java/org/javarosa/xpath/expr/FunctionUtils.java @@ -80,6 +80,7 @@ public class FunctionUtils { funcList.put(XPathUuidFunc.NAME, XPathUuidFunc.class); funcList.put(XPathIdCompressFunc.NAME, XPathIdCompressFunc.class); funcList.put(XPathJoinChunkFunc.NAME, XPathJoinChunkFunc.class); + funcList.put(XPathChecksumFunc.NAME, XPathChecksumFunc.class); } private static final CacheTable mDoubleParseCache = new CacheTable<>(); diff --git a/src/main/java/org/javarosa/xpath/expr/XPathChecksumFunc.java b/src/main/java/org/javarosa/xpath/expr/XPathChecksumFunc.java index c9010c70ad..79dde2716b 100644 --- a/src/main/java/org/javarosa/xpath/expr/XPathChecksumFunc.java +++ b/src/main/java/org/javarosa/xpath/expr/XPathChecksumFunc.java @@ -1,5 +1,6 @@ package org.javarosa.xpath.expr; + import org.commcare.cases.util.StringUtils; import org.javarosa.core.model.condition.EvaluationContext; import org.javarosa.core.model.instance.DataInstance; @@ -7,6 +8,10 @@ import org.javarosa.xpath.XPathUnsupportedException; import org.javarosa.xpath.parser.XPathSyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + public class XPathChecksumFunc extends XPathFuncExpr { public static final String NAME = "checksum"; private static final int EXPECTED_ARG_COUNT = 2; @@ -32,7 +37,7 @@ public Object evalBody(DataInstance model, EvaluationContext evalContext, Object * @param o2 input we are calculating checksum for * @return checksum of {@code o2} calculated using {@code o1} type algorithm */ - private String checksum(Object o1, Object o2) { + private static String checksum(Object o1, Object o2) { String algorithmKey = FunctionUtils.toString(o1); String input = FunctionUtils.toString(o2); @@ -40,7 +45,7 @@ private String checksum(Object o1, Object o2) { case ALGORITHM_KEY_VERHOEFF: return verhoeffChecksum(input); default: - throw new XPathUnsupportedException("Algorithm key " + algorithmKey + " is not supported for checksum"); + throw new XPathUnsupportedException("Bad algorithm key " + algorithmKey + ". We only support 'verhoeff' as algorithm key right now."); } } @@ -51,7 +56,7 @@ private String checksum(Object o1, Object o2) { * @return Verhoeff checksum value for {@code input} * @see Based on Verhoeff checksum implementation here */ - private String verhoeffChecksum(String input) { + private static String verhoeffChecksum(String input) { // The multiplication table int[][] op = new int[][]{ @@ -82,12 +87,12 @@ private String verhoeffChecksum(String input) { // The inverse table int[] inv = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9}; - int check = 0; + ArrayList inputList = StringUtils.toList(input); + Collections.reverse(inputList); - String[] mArray = ArrayUtilities.reverse(StringUtils.toArray(input), String[].class); - - for (int i = 0; i < mArray.length; i++) { - check = op[check][p[((i + 1) % 8)][Integer.parseInt(mArray[i])]]; + int check = 0; + for (int i = 0; i < inputList.size(); i++) { + check = op[check][p[((i + 1) % 8)][Character.getNumericValue(inputList.get(i))]]; } return Integer.toString(inv[check]); diff --git a/src/test/java/org/javarosa/xpath/test/XPathEvalTest.java b/src/test/java/org/javarosa/xpath/test/XPathEvalTest.java index 5d53b2d2c2..db7d0c0f14 100755 --- a/src/test/java/org/javarosa/xpath/test/XPathEvalTest.java +++ b/src/test/java/org/javarosa/xpath/test/XPathEvalTest.java @@ -58,8 +58,8 @@ private void testEval(String expr, FormInstance model, EvaluationContext ec, Obj if (exceptionExpected) { fail("Expected exception, expression : " + expr); } else if ((result instanceof Double && expected instanceof Double)) { - Double o = (Double) result; - Double t = (Double) expected; + Double o = (Double)result; + Double t = (Double)expected; if (Math.abs(o - t) > DOUBLE_TOLERANCE) { fail("Doubles outside of tolerance [" + o + "," + t + " ]"); } else if (Double.isNaN(o) && !Double.isNaN(t)) { @@ -678,12 +678,12 @@ private TreeReference inlinePositionArgs(TreeReference treeRef) { if (!(predicates.elementAt(0) instanceof XPathNumericLiteral)) { throw new IllegalArgumentException("only position [] predicates allowed"); } - double d = ((XPathNumericLiteral) predicates.elementAt(0)).d; - if (d != (double) ((int) d)) { + double d = ((XPathNumericLiteral)predicates.elementAt(0)).d; + if (d != (double)((int)d)) { throw new IllegalArgumentException("invalid position: " + d); } - int multiplicity = (int) d - 1; + int multiplicity = (int)d - 1; if (treeRef.getMultiplicity(i) != TreeReference.INDEX_UNBOUND) { throw new IllegalArgumentException("Cannot inline already qualified steps"); } @@ -769,7 +769,7 @@ public boolean rawArgs() { @Override public Object eval(Object[] args, EvaluationContext ec) { - return new Double(((Double) args[0]).doubleValue() + ((Double) args[1]).doubleValue()); + return new Double(((Double)args[0]).doubleValue() + ((Double)args[1]).doubleValue()); } }); @@ -929,7 +929,7 @@ public boolean rawArgs() { @Override public Object eval(Object[] args, EvaluationContext ec) { - return ((Boolean) args[0]).booleanValue() ? new CustomSubType() : new CustomType(); + return ((Boolean)args[0]).booleanValue() ? new CustomSubType() : new CustomType(); } }); @@ -982,7 +982,7 @@ private String printArgs(Object[] oa) { int lastIndex = Math.max(fullName.lastIndexOf('.'), fullName.lastIndexOf('$')); sb.append(fullName.substring(lastIndex + 1, fullName.length())); sb.append(":"); - sb.append(oa[i] instanceof Date ? DateUtils.formatDate((Date) oa[i], DateUtils.FORMAT_ISO8601) : oa[i].toString()); + sb.append(oa[i] instanceof Date ? DateUtils.formatDate((Date)oa[i], DateUtils.FORMAT_ISO8601) : oa[i].toString()); if (i < oa.length - 1) sb.append(","); } @@ -1059,7 +1059,7 @@ public Vector getPrototypes() { @Override public Object eval(Object[] args, EvaluationContext ec) { - val = (String) args[0]; + val = (String)args[0]; return Boolean.TRUE; } }; From 63d9cc738ef2e53aed6c7c002e50d107fb81b7b1 Mon Sep 17 00:00:00 2001 From: ALIZA STONE Date: Fri, 7 Jul 2017 12:20:51 -0400 Subject: [PATCH 4/4] Set authority for profile install based on install mode --- .../org/commcare/util/engine/CommCareConfigEngine.java | 6 ++++-- .../java/org/commcare/resources/ResourceManager.java | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/cli/java/org/commcare/util/engine/CommCareConfigEngine.java b/src/cli/java/org/commcare/util/engine/CommCareConfigEngine.java index 17bdbf48d8..439414c3d5 100644 --- a/src/cli/java/org/commcare/util/engine/CommCareConfigEngine.java +++ b/src/cli/java/org/commcare/util/engine/CommCareConfigEngine.java @@ -214,9 +214,11 @@ private void init(String profileRef) { } } - public void installAppFromReference(String profileReference) throws UnresolvedResourceException, + public void installAppFromReference(String profileReference) + throws UnresolvedResourceException, UnfullfilledRequirementsException, InstallCancelledException { - ResourceManager.installAppResources(platform, profileReference, this.table, true); + ResourceManager.installAppResources(platform, profileReference, this.table, true, + Resource.RESOURCE_AUTHORITY_LOCAL); } public void initEnvironment() { diff --git a/src/main/java/org/commcare/resources/ResourceManager.java b/src/main/java/org/commcare/resources/ResourceManager.java index ecd6abd7ae..7017f4d063 100644 --- a/src/main/java/org/commcare/resources/ResourceManager.java +++ b/src/main/java/org/commcare/resources/ResourceManager.java @@ -50,7 +50,8 @@ public ResourceManager(CommCarePlatform platform, * version numbers? */ public static void installAppResources(CommCarePlatform platform, String profileReference, - ResourceTable global, boolean forceInstall) + ResourceTable global, boolean forceInstall, + int authorityForProfile) throws UnfullfilledRequirementsException, UnresolvedResourceException, InstallCancelledException { @@ -64,11 +65,10 @@ public static void installAppResources(CommCarePlatform platform, String profile global.getResourceWithId(CommCarePlatform.APP_PROFILE_RESOURCE_ID); if (profile == null) { - // grab the local profile and parse it + // Create a stub for the profile resource that points to the authority and location + // from which we will install it Vector locations = new Vector<>(); - locations.addElement(new ResourceLocation(Resource.RESOURCE_AUTHORITY_LOCAL, profileReference)); - - // We need a way to identify this version... + locations.addElement(new ResourceLocation(authorityForProfile, profileReference)); Resource r = new Resource(Resource.RESOURCE_VERSION_UNKNOWN, CommCarePlatform.APP_PROFILE_RESOURCE_ID, locations, "Application Descriptor");