/**
*
*/
package org.commcare.android.resource.installers;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.commcare.android.javarosa.AndroidLogger;
import org.commcare.android.util.AndroidCommCarePlatform;
import org.commcare.android.util.DummyResourceTable;
import org.commcare.dalvik.application.CommCareApp;
import org.commcare.dalvik.application.CommCareApplication;
import org.commcare.resources.model.Resource;
import org.commcare.resources.model.ResourceInitializationException;
import org.commcare.resources.model.ResourceLocation;
import org.commcare.resources.model.ResourceTable;
import org.commcare.resources.model.UnresolvedResourceException;
import org.commcare.suite.model.Profile;
import org.commcare.suite.model.PropertySetter;
import org.commcare.xml.ProfileParser;
import org.commcare.xml.util.InvalidStructureException;
import org.commcare.xml.util.UnfullfilledRequirementsException;
import org.javarosa.core.reference.InvalidReferenceException;
import org.javarosa.core.reference.Reference;
import org.javarosa.core.reference.ReferenceManager;
import org.javarosa.core.services.Logger;
import org.javarosa.core.util.externalizable.DeserializationException;
import org.javarosa.core.util.externalizable.PrototypeFactory;
import org.xmlpull.v1.XmlPullParserException;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.preference.PreferenceManager;
/**
* @author ctsims
*
*/
public class ProfileAndroidInstaller extends FileSystemInstaller {
public ProfileAndroidInstaller() {
}
public ProfileAndroidInstaller(String localDestination, String upgradeDestination) {
super(localDestination, upgradeDestination);
}
/* (non-Javadoc)
* @see org.commcare.resources.model.ResourceInstaller#initialize(org.commcare.util.CommCareInstance)
*/
public boolean initialize(AndroidCommCarePlatform instance) throws ResourceInitializationException {
try {
Reference local = ReferenceManager._().DeriveReference(localLocation);
ProfileParser parser = new ProfileParser(local.getStream(), instance, instance.getGlobalResourceTable(), null,
Resource.RESOURCE_STATUS_INSTALLED, false);
Profile p = parser.parse();
instance.setProfile(p);
return true;
} catch (InvalidReferenceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidStructureException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnfullfilledRequirementsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
public boolean install(Resource r, ResourceLocation location, Reference ref, ResourceTable table, AndroidCommCarePlatform instance, boolean upgrade) throws UnresolvedResourceException, UnfullfilledRequirementsException{
//First, make sure all the file stuff is managed.
super.install(r, location, ref, table, instance, upgrade);
try {
Reference local = ReferenceManager._().DeriveReference(localLocation);
ProfileParser parser = new ProfileParser(local.getStream(), instance, table, r.getRecordGuid(),
upgrade ? Resource.RESOURCE_STATUS_UNINITIALIZED : Resource.RESOURCE_STATUS_UNINITIALIZED, false);
Profile p = parser.parse();
if(!upgrade) {
initProperties(p);
}
table.commit(r, upgrade ? Resource.RESOURCE_STATUS_UPGRADE : Resource.RESOURCE_STATUS_INSTALLED, p.getVersion());
return true;
} catch (InvalidReferenceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidStructureException e) {
throw new UnresolvedResourceException(r, "Invalid content in the Profile Definition: " + e.getMessage(), true);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
private void initProperties(Profile profile) {
//Baaaaaad. Encapsulate this better!!!
SharedPreferences prefs = CommCareApp.currentSandbox.getAppPreferences();
Editor editor = prefs.edit();
for(PropertySetter p : profile.getPropertySetters()) {
editor.putString(p.getKey(), p.isForce() ? p.getValue() : prefs.getString(p.getKey(), p.getValue()));
}
editor.commit();
}
/* (non-Javadoc)
* @see org.commcare.resources.model.ResourceInstaller#upgrade(org.commcare.resources.model.Resource, org.commcare.resources.model.ResourceTable)
*/
public boolean upgrade(Resource r) {
if(!super.upgrade(r)) {
return false;
}
try {
Reference local = ReferenceManager._().DeriveReference(localLocation);
//Create a parser with no side effects
ProfileParser parser = new ProfileParser(local.getStream(), null, new DummyResourceTable(), null, Resource.RESOURCE_STATUS_INSTALLED, false);
//Parse just the file (for the properties)
Profile p = parser.parse();
initProperties(p);
} catch (InvalidReferenceException e) {
e.printStackTrace();
Logger.log(AndroidLogger.TYPE_RESOURCES, "Profile not available after upgrade: " + e.getMessage());
return false;
} catch (IOException e) {
Logger.log(AndroidLogger.TYPE_RESOURCES, "Profile not available after upgrade: " + e.getMessage());
return false;
} catch (InvalidStructureException e) {
Logger.log(AndroidLogger.TYPE_RESOURCES, "Profile not available after upgrade: " + e.getMessage());
return false;
} catch (UnfullfilledRequirementsException e) {
Logger.log(AndroidLogger.TYPE_RESOURCES, "Profile not available after upgrade: " + e.getMessage());
return false;
} catch (XmlPullParserException e) {
Logger.log(AndroidLogger.TYPE_RESOURCES, "Profile not available after upgrade: " + e.getMessage());
return false;
}
return true;
}
protected int customInstall(Resource r, Reference local, boolean upgrade) throws IOException, UnresolvedResourceException {
return Resource.RESOURCE_STATUS_LOCAL;
}
/* (non-Javadoc)
* @see org.commcare.resources.model.ResourceInstaller#requiresRuntimeInitialization()
*/
public boolean requiresRuntimeInitialization() {
return true;
}
/* (non-Javadoc)
* @see org.javarosa.core.util.externalizable.Externalizable#readExternal(java.io.DataInputStream, org.javarosa.core.util.externalizable.PrototypeFactory)
*/
public void readExternal(DataInputStream in, PrototypeFactory pf) throws IOException, DeserializationException {
super.readExternal(in, pf);
}
/* (non-Javadoc)
* @see org.javarosa.core.util.externalizable.Externalizable#writeExternal(java.io.DataOutputStream)
*/
public void writeExternal(DataOutputStream out) throws IOException {
super.writeExternal(out);
}
}