blob: 0d5b8ffa5e402ca29c9f4904c48a2be16b0058e0 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.motorola.studio.android.db.deployment;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.util.NLS;
import com.motorola.studio.android.codeutils.db.utils.DatabaseUtils;
import com.motorola.studio.android.codeutils.i18n.CodeUtilsNLS;
import com.motorola.studio.android.common.IAndroidConstants;
import com.motorola.studio.android.common.exception.AndroidException;
import com.motorola.studio.android.common.utilities.FileUtil;
import com.motorola.studio.android.manifest.AndroidProjectManifestFile;
import com.motorola.studio.android.model.manifest.AndroidManifestFile;
import com.motorola.studio.android.model.manifest.dom.ApplicationNode;
import com.motorola.studio.android.model.manifest.dom.ManifestNode;
import com.motorola.studio.android.model.manifest.dom.ProviderNode;
/**
* Creates Content Provider that have methods to copy .db file.
*/
public class ContentProviderDeployer
{
/*
* Plug-in Identifier
*/
private static final String PLUGIN_IDENTIFIER = "com.motorola.studio.android.codeutils";
/**
* Constant representing the location of the DataaseHelper class.
*/
public static final String CONTENT_PROVIDER_HELPER_CLASS_LOCATION =
"resources/databaseDeploy/ContentProviderHelperjava.txt"; //$NON-NLS-1$
/**
* This constant represents the value of newly-create Application Package Name for the Content Provider.
*/
public static final String APPLICATION_PACKAGE_NAMESPACE = "#applicationPackageNamespace#";
/**
* Directory of the ContentProvider Helper in the android project.
*/
public static final String ANDROID_PROJECT_PACKAGE_NAME = "#packageName#"; //$NON-NLS-1$
/**
* File name of the ContentProvider Helper in the android project.
*/
public static final String CONTENT_PROVIDER_CLASS_NAME = "#className#"; //$NON-NLS-1$
public static final String CONTENT_PROVIDER_AUTHORITY = "#authority#"; //$NON-NLS-1$
/**
* Copy the ContentProvider Helper deploy file to the newly-created-android project.
*
* @param project Project where the files will be copied to
* @param parameters Copy parameters
* @param templateLocation The template (origin) location
* @param needToAddOnManifest <code>true</code> in case the manifest is to be updated, false otherwise
* @param overrideConentProviderIfExists <code>true</code> in case the Content Providers must be overridden
* in case they exist
* @param monitor UI monitor
*
* @throws IOException Exception thrown in case there are problems accessing data of a file.
* @throws CoreException Exception thrown in case there are problems accessing a file itself.
*/
public static void copyContentProviderHelperClassToProject(IProject project,
Map<String, String> parameters, String templateLocation, boolean needToAddOnManifest,
boolean overrideConentProviderIfExists, IProgressMonitor monitor) throws IOException,
CoreException
{
// get the destination folder
IFolder destinationFolder =
project.getFolder(IAndroidConstants.WS_ROOT + IAndroidConstants.FD_SOURCES);
// split the new sequence of folders - they will be created, one by one
String[] folders =
parameters.get(ANDROID_PROJECT_PACKAGE_NAME).split(IAndroidConstants.RE_DOT);
// iterate through the folders and create them
if ((folders != null) && (folders.length > 0))
{
// iterate
for (String folder : folders)
{
// get destination folder with the next one to be created
destinationFolder = destinationFolder.getFolder(folder);
// proceed in case the destination folder does not exists and can be created
if (!destinationFolder.exists())
{
// create the folder
destinationFolder.create(true, true, monitor);
}
}
}
// get the destination file
IFile destinationFile =
destinationFolder.getFile(parameters.get(CONTENT_PROVIDER_CLASS_NAME)
+ IAndroidConstants.DOT_JAVA);
//refresh to avoid inconsistency
destinationFile.getParent().refreshLocal(IResource.DEPTH_INFINITE, monitor);
// proceed in case it does not exist and can be created
if ((!destinationFile.exists() || overrideConentProviderIfExists)
&& FileUtil.canWrite(destinationFile))
{
// get the Database Helper class as a text
String databaseHelperText =
readContentProviderHelperClassFile(project, parameters, templateLocation);
// transform it in a stream
InputStream stream = null;
try
{
stream = new ByteArrayInputStream(databaseHelperText.getBytes("UTF-8")); //$NON-NLS-1$
// if the file exists, delete it
if (destinationFile.exists())
{
destinationFile.delete(true, monitor);
}
// create the destination file
destinationFile.create(stream, true, monitor);
DatabaseUtils.formatCode(destinationFile, databaseHelperText, monitor);
}
finally
{
if (stream != null)
{
stream.close();
}
}
}
if (needToAddOnManifest)
{
try
{
String className = parameters.get(CONTENT_PROVIDER_CLASS_NAME);
String packageName = parameters.get(ANDROID_PROJECT_PACKAGE_NAME);
createProviderOnManifest(project, className, packageName, monitor);
}
catch (AndroidException e)
{
throw new IOException(e.getMessage());
}
}
}
/**
* Read the ContentProvider Helper class file, replace the parameter maps
* and return it as a String.
*
* @param project Project where the ContentProviderHelper is retrieved.
* @param parameters Parameters for replacement in the ContentProviderHelper class file.
*
* @return a String representing the ContentProviderHelper class file.
*
* @throws IOException Exception thrown when there are problems reading elements from the
* ContentProviderHelper class file.
*/
private static String readContentProviderHelperClassFile(IProject project,
Map<String, String> parameters, String templateLocation) throws IOException
{
URL url = Platform.getBundle(PLUGIN_IDENTIFIER).getEntry(templateLocation);
url = FileLocator.toFileURL(url);
// string buffer which holds the file as a text
StringBuffer contentProviderHelperBuffer = new StringBuffer("");
// reader
BufferedReader contentProviderHelperReader = null;
// get the file to be read
File f = null;
try
{
f = new File(url.getFile());
// create the reader to manipulate the file
contentProviderHelperReader = new BufferedReader(new FileReader(f));
// read the Database Helper class file in steps (using buffer)
String buffer = null;
// iterate while there is stuff to read
while ((buffer = contentProviderHelperReader.readLine()) != null)
{
// read and put the content in the string buffer element
contentProviderHelperBuffer.append(buffer);
contentProviderHelperBuffer.append(System.getProperty("line.separator"));
}
}
finally
{
// close reader
if (contentProviderHelperReader != null)
{
contentProviderHelperReader.close();
}
}
// string holding the "text" of the ContentProvider class
String contentProviderHelperText = "";
// proceed in case there is stuff in the buffer to read
if (contentProviderHelperBuffer != null)
{
contentProviderHelperText = contentProviderHelperBuffer.toString();
// iterate through the parameters and replace the parameters in the map
if (parameters != null)
{
for (String key : parameters.keySet())
{
// replace all the keys
contentProviderHelperText =
contentProviderHelperText.replaceAll(key, parameters.get(key));
}
}
}
// return the file as a text
return contentProviderHelperText;
}
/**
* Creates the Content Provider class entry on AndroidManifest.xml file
*
* @param monitor the progress monitor
*
* @return true if the entry has been added or false otherwise
* @throws AndroidException
*/
private static boolean createProviderOnManifest(IProject project, String className,
String packageName, IProgressMonitor monitor) throws AndroidException
{
boolean created = false;
try
{
int manifestUpdatingSteps = 4;
int totalWork = manifestUpdatingSteps;
monitor.beginTask("", totalWork);
monitor.subTask(CodeUtilsNLS.UI_Common_UpdatingTheAndroidManifestXMLFile);
AndroidManifestFile androidManifestFile =
AndroidProjectManifestFile.getFromProject(project);
monitor.worked(1);
ManifestNode manifestNode =
androidManifestFile != null ? androidManifestFile.getManifestNode() : null;
ApplicationNode applicationNode =
manifestNode != null ? manifestNode.getApplicationNode() : null;
monitor.worked(1);
if (applicationNode != null)
{
ProviderNode providerNode =
new ProviderNode(className, packageName + "." + className.toLowerCase());
String authority = packageName + "." + className.toLowerCase();
providerNode.addAuthority(authority);
String name = packageName + "." + className;
providerNode.setName(name);
// get all provider nodes
List<ProviderNode> providerNodes = applicationNode.getProviderNodes();
// see whether the node to be inserted is already in the list - in case it is not, add it, otherwise do nothing
boolean hasProviderNode = false;
// verify in case the list of nodes is not empty
if ((providerNodes != null) && (providerNodes.size() > 0))
{
// iterate through the list
for (ProviderNode retrievedProvidedNode : providerNodes)
{
// match the nodes
if (retrievedProvidedNode.getName().equals(providerNode.getName()))
{
// in case a match is found, set the flag and leave the loop
hasProviderNode = true;
break;
}
}
}
// in case there is not this provider node, add it
if (!hasProviderNode)
{
applicationNode.addProviderNode(providerNode);
}
monitor.worked(1);
monitor.subTask(CodeUtilsNLS.UI_Common_SavingTheAndroidManifestXMLFile);
AndroidProjectManifestFile.saveToProject(project, androidManifestFile, true);
created = true;
monitor.worked(1);
}
}
catch (AndroidException e)
{
String errMsg =
NLS.bind(CodeUtilsNLS.EXC_ContentProvider_CannotUpdateTheManifestFile,
className, e.getLocalizedMessage());
throw new AndroidException(errMsg);
}
catch (CoreException e)
{
String errMsg =
NLS.bind(CodeUtilsNLS.EXC_ContentProvider_CannotUpdateTheManifestFile,
className, e.getLocalizedMessage());
throw new AndroidException(errMsg);
}
finally
{
monitor.done();
}
return created;
}
}