diff --git a/src/main/java/org/commcare/resources/model/ResourceTable.java b/src/main/java/org/commcare/resources/model/ResourceTable.java index 11a06d761d..38b9e8db15 100644 --- a/src/main/java/org/commcare/resources/model/ResourceTable.java +++ b/src/main/java/org/commcare/resources/model/ResourceTable.java @@ -942,7 +942,7 @@ public void initializeResources(CommCarePlatform platform, boolean isUpgrade) th setMissingResources(missingResources); } - private void attemptResourceInitialization(CommCarePlatform platform, boolean isUpgrade, + public void attemptResourceInitialization(CommCarePlatform platform, boolean isUpgrade, Resource r, Vector missingResources) throws ResourceInitializationException { try { r.getInstaller().initialize(platform, isUpgrade); diff --git a/src/main/java/org/commcare/suite/model/Credential.java b/src/main/java/org/commcare/suite/model/Credential.java new file mode 100644 index 0000000000..600b55ec7b --- /dev/null +++ b/src/main/java/org/commcare/suite/model/Credential.java @@ -0,0 +1,59 @@ +package org.commcare.suite.model; + +import org.javarosa.core.util.externalizable.DeserializationException; +import org.javarosa.core.util.externalizable.ExtUtil; +import org.javarosa.core.util.externalizable.Externalizable; +import org.javarosa.core.util.externalizable.PrototypeFactory; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Apps use this model to convey the types of credentials it issues + */ +public class Credential implements Externalizable { + + private String level; + private String type; + + /** + * Serialization Only!!! + */ + public Credential() { + } + + public Credential(String level, String type) { + this.level = level; + this.type = type; + } + + @Override + public void readExternal(DataInputStream in, PrototypeFactory pf) + throws IOException, DeserializationException { + level = ExtUtil.readString(in); + type = ExtUtil.readString(in); + } + + @Override + public void writeExternal(DataOutputStream out) throws IOException { + ExtUtil.writeString(out, level); + ExtUtil.writeString(out, type); + } + + public String getLevel() { + return level; + } + + public String getType() { + return type; + } + + @Override + public String toString() { + return "Credential{" + + "level='" + level + '\'' + + ", type='" + type + '\'' + + '}'; + } +} diff --git a/src/main/java/org/commcare/suite/model/Profile.java b/src/main/java/org/commcare/suite/model/Profile.java index 92d535a0b4..42dfa6de5e 100644 --- a/src/main/java/org/commcare/suite/model/Profile.java +++ b/src/main/java/org/commcare/suite/model/Profile.java @@ -48,6 +48,7 @@ public class Profile implements Persistable { * were added for multiple app seating functionality */ private boolean fromOld; + private Vector credentials; @SuppressWarnings("unused") public Profile() { @@ -77,6 +78,7 @@ public Profile(int version, String authRef, String uniqueId, String displayName, properties = new Vector<>(); roots = new Vector<>(); dependencies = new Vector<>(); + credentials = new Vector<>(); featureStatus = new Hashtable<>(); //turn on default features featureStatus.put("users", true); @@ -191,6 +193,14 @@ public void setDependencies(Vector dependencies) { this.dependencies = dependencies; } + public void setCredentials(Vector credentials) { + this.credentials = credentials; + } + + public Vector getCredentials() { + return credentials; + } + /** * A helper method which initializes the properties specified * by this profile definition. @@ -228,6 +238,8 @@ public void readExternal(DataInputStream in, PrototypeFactory pf) buildProfileId = ExtUtil.readString(in); dependencies = (Vector)ExtUtil.read(in, new ExtWrapList(AndroidPackageDependency.class), pf); + credentials = (Vector)ExtUtil.read(in, + new ExtWrapList(Credential.class), pf); } @Override @@ -244,5 +256,6 @@ public void writeExternal(DataOutputStream out) throws IOException { ExtUtil.write(out, new ExtWrapMap(featureStatus)); ExtUtil.writeString(out, buildProfileId); ExtUtil.write(out, new ExtWrapList(dependencies)); + ExtUtil.write(out, new ExtWrapList(credentials)); } } diff --git a/src/main/java/org/commcare/xml/ProfileParser.java b/src/main/java/org/commcare/xml/ProfileParser.java index 54e2183976..cbc46802ae 100644 --- a/src/main/java/org/commcare/xml/ProfileParser.java +++ b/src/main/java/org/commcare/xml/ProfileParser.java @@ -3,9 +3,11 @@ */ package org.commcare.xml; +import org.commcare.cases.util.StringUtils; import org.commcare.resources.model.Resource; import org.commcare.resources.model.ResourceTable; import org.commcare.suite.model.AndroidPackageDependency; +import org.commcare.suite.model.Credential; import org.commcare.suite.model.Profile; import org.commcare.util.CommCarePlatform; import org.javarosa.core.reference.RootTranslator; @@ -27,7 +29,11 @@ public class ProfileParser extends ElementParser { private static final String NAME_DEPENDENCIES = "dependencies"; private static final String NAME_ANDROID_PACKAGE = "android_package"; + private static final String NAME_CREDENTIALS = "credentials"; + private static final String NAME_CREDENTIAL = "credential"; private static final String ATTR_ID = "id"; + private static final String ATTR_CREDENTIAL_LEVEL = "level"; + private static final String ATTR_CREDENTIAL_TYPE = "type"; ResourceTable table; String resourceId; @@ -244,6 +250,8 @@ private void parseFeatures(Profile profile) throws XmlPullParserException, IOExc } else if (tag.equals(NAME_DEPENDENCIES)) { profile.setDependencies(parseDependencies()); } else if (tag.equals("sense")) { + }else if (tag.equals(NAME_CREDENTIALS)) { + profile.setCredentials(parseCredentials()); } profile.setFeatureActive(tag, isActive); @@ -251,6 +259,26 @@ private void parseFeatures(Profile profile) throws XmlPullParserException, IOExc } } + private Vector parseCredentials() + throws InvalidStructureException, XmlPullParserException, IOException { + Vector appCredentials = new Vector<>(); + while (nextTagInBlock(NAME_CREDENTIALS)) { + String tag = parser.getName().toLowerCase(); + if (tag.equals(NAME_CREDENTIAL)) { + String level = parser.getAttributeValue(null, ATTR_CREDENTIAL_LEVEL); + String type = parser.getAttributeValue(null, ATTR_CREDENTIAL_TYPE); + if (StringUtils.isEmpty(level)) { + throw new InvalidStructureException("No level defined for credential"); + } + if (StringUtils.isEmpty(type)) { + throw new InvalidStructureException("No type defined for credential"); + } + appCredentials.add(new Credential(level, type)); + } + } + return appCredentials; + } + private Vector parseDependencies() throws InvalidStructureException, XmlPullParserException, IOException { Vector appDependencies = new Vector<>(); diff --git a/src/test/java/org/commcare/backend/suite/model/test/ProfileTests.java b/src/test/java/org/commcare/backend/suite/model/test/ProfileTests.java index 3493c724d2..29cb575b8d 100644 --- a/src/test/java/org/commcare/backend/suite/model/test/ProfileTests.java +++ b/src/test/java/org/commcare/backend/suite/model/test/ProfileTests.java @@ -9,6 +9,7 @@ import org.commcare.resources.model.Resource; import org.commcare.resources.model.ResourceTable; import org.commcare.suite.model.AndroidPackageDependency; +import org.commcare.suite.model.Credential; import org.commcare.suite.model.Profile; import org.commcare.test.utilities.PersistableSandbox; import org.commcare.util.engine.CommCareConfigEngine; @@ -92,6 +93,16 @@ public void testDependenciesParse() { assertEquals(Arrays.toString(expectedDependencies),Arrays.toString(p.getDependencies().toArray())); } + @Test + public void testCredentialsParse() { + Profile p = getProfile(BASIC_PROFILE_PATH); + assertTrue(p.isFeatureActive("credentials")); + Credential[] expectedCredentials = new Credential[2]; + expectedCredentials[0] = new Credential("3MON_ACTIVE", "APP_ACTIVITY"); + expectedCredentials[1] = new Credential("6MON_ACTIVE", "APP_ACTIVITY"); + assertEquals(Arrays.toString(expectedCredentials),Arrays.toString(p.getCredentials().toArray())); + } + private void compareProfiles(Profile a, Profile b) { if(!ArrayUtilities.arraysEqual(a.getPropertySetters(), b.getPropertySetters())) { fail("Mismatch of property setters between profiles"); diff --git a/src/test/resources/basic_profile.ccpr b/src/test/resources/basic_profile.ccpr index ff9f0c2dfa..0fd3095017 100644 --- a/src/test/resources/basic_profile.ccpr +++ b/src/test/resources/basic_profile.ccpr @@ -91,6 +91,11 @@ + + + + +