package org.commcare.android.resource.installers;
import android.util.Log;
import org.commcare.resources.model.InvalidResourceException;
import org.commcare.resources.model.MissingMediaException;
import org.commcare.resources.model.Resource;
import org.commcare.resources.model.ResourceLocation;
import org.commcare.resources.model.ResourceTable;
import org.commcare.resources.model.UnresolvedResourceException;
import org.commcare.suite.model.Entry;
import org.commcare.suite.model.Menu;
import org.commcare.suite.model.Suite;
import org.commcare.utils.AndroidCommCarePlatform;
import org.commcare.utils.DummyResourceTable;
import org.commcare.utils.FileUtil;
import org.commcare.xml.AndroidSuiteParser;
import org.commcare.xml.SuiteParser;
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.xml.util.InvalidStructureException;
import org.javarosa.xml.util.UnfullfilledRequirementsException;
import org.javarosa.xpath.XPathException;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* @author ctsims
*/
public class SuiteAndroidInstaller extends FileSystemInstaller {
private static final String TAG = SuiteAndroidInstaller.class.getSimpleName();
@SuppressWarnings("unused")
public SuiteAndroidInstaller() {
// for externalization
}
public SuiteAndroidInstaller(String localDestination, String upgradeDestination) {
super(localDestination, upgradeDestination);
}
@Override
public boolean initialize(final AndroidCommCarePlatform instance, boolean isUpgrade) {
try {
if (localLocation == null) {
throw new RuntimeException("Error initializing the suite, its file location is null!");
}
Reference local = ReferenceManager.instance().DeriveReference(localLocation);
SuiteParser parser;
if (isUpgrade) {
parser = AndroidSuiteParser.buildUpgradeParser(local.getStream(), instance.getGlobalResourceTable(), instance.getFixtureStorage());
} else {
parser = AndroidSuiteParser.buildInitParser(local.getStream(), instance.getGlobalResourceTable(), instance.getFixtureStorage());
}
Suite s = parser.parse();
instance.registerSuite(s);
return true;
} catch (InvalidStructureException | InvalidReferenceException
| IOException | XmlPullParserException
| UnfullfilledRequirementsException e) {
e.printStackTrace();
}
return false;
}
@Override
public boolean install(Resource r, ResourceLocation location, Reference ref,
ResourceTable table, final 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.instance().DeriveReference(localLocation);
AndroidSuiteParser.buildInstallParser(local.getStream(), table, r.getRecordGuid(), instance.getFixtureStorage()).parse();
table.commitCompoundResource(r, upgrade ? Resource.RESOURCE_STATUS_UPGRADE : Resource.RESOURCE_STATUS_INSTALLED);
return true;
} catch (InvalidStructureException e) {
// push up suite config issues so user can act on them
throw new InvalidResourceException(r.getDescriptor(), e.getMessage());
} catch (XmlPullParserException | InvalidReferenceException
| IOException | XPathException e) {
e.printStackTrace();
}
return false;
}
@Override
protected int customInstall(Resource r, Reference local, boolean upgrade) throws IOException, UnresolvedResourceException {
return Resource.RESOURCE_STATUS_LOCAL;
}
@Override
public boolean requiresRuntimeInitialization() {
return true;
}
@Override
public boolean verifyInstallation(Resource r, Vector<MissingMediaException> problems) {
try {
Reference local = ReferenceManager.instance().DeriveReference(localLocation);
Suite suite = AndroidSuiteParser.buildVerifyParser(local.getStream(), new DummyResourceTable()).parse();
Hashtable<String, Entry> mHashtable = suite.getEntries();
for (Enumeration en = mHashtable.keys(); en.hasMoreElements(); ) {
String key = (String)en.nextElement();
Entry mEntry = mHashtable.get(key);
FileUtil.checkReferenceURI(r, mEntry.getAudioURI(), problems);
FileUtil.checkReferenceURI(r, mEntry.getImageURI(), problems);
}
for (Menu menu : suite.getMenus()) {
FileUtil.checkReferenceURI(r, menu.getAudioURI(), problems);
FileUtil.checkReferenceURI(r, menu.getImageURI(), problems);
}
} catch (Exception e) {
Logger.log("e", "suite validation failed with: " + e.getMessage());
Log.d(TAG, "Suite validation failed");
e.printStackTrace();
}
return problems.size() != 0;
}
}