/* * 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.model; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.wizard.IWizardContainer; import org.eclipse.osgi.util.NLS; 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.manifest.AndroidProjectManifestFile; import com.motorola.studio.android.model.java.ServiceClass; 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.IntentFilterNode; import com.motorola.studio.android.model.manifest.dom.ManifestNode; import com.motorola.studio.android.model.manifest.dom.ServiceNode; import com.motorola.studio.android.model.manifest.dom.UsesPermissionNode; import com.motorola.studio.android.model.resources.ResourceFile; import com.motorola.studio.android.model.resources.types.AbstractResourceNode.NodeType; import com.motorola.studio.android.model.resources.types.ResourcesNode; import com.motorola.studio.android.model.resources.types.StringNode; import com.motorola.studio.android.resources.AndroidProjectResources; /** * Class that provides a service model to be used for the service wizard. */ public class Service extends Launcher { private static final String SERVICE_RESOURCE_LABEL_SUFFIX = "ServiceLabel"; //$NON-NLS-1$ private static final int MANIFEST_UPDATING_STEPS = 6; private static final int RESOURCES_UPDATING_STEPS = 3; private boolean onStartMethod; private boolean onCreateMethod; /** * Default constructor. * */ public Service() { super(IAndroidConstants.CLASS_SERVICE); } /* * (non-Javadoc) * @see com.motorola.studio.android.model.BuildingBlockModel#getStatus() */ @Override public IStatus getStatus() { return super.getStatus(); } /** * Create a new service class and add it to the manifest file. * @return True if the service class was successfully created and added to the manifest file. Otherwise, returns false. * */ @Override public boolean save(IWizardContainer container, IProgressMonitor monitor) throws AndroidException { boolean classCreated = createServiceClass(monitor); boolean addedOnManifest = false; if (classCreated) { addedOnManifest = createServiceOnManifest(monitor); } // Logs all permissions used in UDC log super.save(container, monitor); return classCreated && addedOnManifest; } /* * (non-Javadoc) * @see com.motorola.studio.android.model.IWizardModel#needMoreInformation() */ public boolean needMoreInformation() { return false; } /* * Creates the Service java class * * @param monitor the progress monitor * * @return true if the class has been created or false otherwise * @throws AndroidException */ private boolean createServiceClass(IProgressMonitor monitor) throws AndroidException { boolean created = false; monitor.subTask(CodeUtilsNLS.UI_Service_CreatingTheServiceJavaClass); ServiceClass serviceClass = new ServiceClass(getName(), getPackageFragment().getElementName(), onCreateMethod, onStartMethod); try { createJavaClassFile(serviceClass, monitor); created = true; } catch (JavaModelException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_Service_CannotCreateTheServiceClass, getName(), e.getLocalizedMessage()); throw new AndroidException(errMsg); } catch (AndroidException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_Service_CannotCreateTheServiceClass, getName(), e.getLocalizedMessage()); throw new AndroidException(errMsg); } return created; } /* * Creates the Service 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 boolean createServiceOnManifest(IProgressMonitor monitor) throws AndroidException { boolean created = false; try { int totalWork = MANIFEST_UPDATING_STEPS + RESOURCES_UPDATING_STEPS; monitor.beginTask("", totalWork); monitor.subTask(CodeUtilsNLS.UI_Common_UpdatingTheAndroidManifestXMLFile); AndroidManifestFile androidManifestFile = AndroidProjectManifestFile.getFromProject(getProject()); monitor.worked(1); ManifestNode manifestNode = androidManifestFile != null ? androidManifestFile.getManifestNode() : null; ApplicationNode applicationNode = manifestNode != null ? manifestNode.getApplicationNode() : null; monitor.worked(1); if (applicationNode != null) { // Adds the added permission nodes to manifest file List<String> permissionsNames = new ArrayList<String>(); for (UsesPermissionNode i : manifestNode.getUsesPermissionNodes()) { permissionsNames.add(i.getName()); } for (String intentFilterPermission : getIntentFilterPermissionsAsArray()) { if (!permissionsNames.contains(intentFilterPermission)) { manifestNode.addChild(new UsesPermissionNode(intentFilterPermission)); } } boolean serviceExists = false; String classQualifier = (getPackageFragment().getElementName() .equals(manifestNode.getPackageName()) ? "" : getPackageFragment() //$NON-NLS-1$ .getElementName()) + "."; //$NON-NLS-1$ for (ServiceNode serviceNode : applicationNode.getServiceNodes()) { if (serviceNode.getName().equals(getName())) { serviceExists = true; break; } } monitor.worked(1); if (!serviceExists) { ServiceNode serviceNode = new ServiceNode(classQualifier + getName()); String serviceLabel = createServiceLabel(monitor); if (serviceLabel != null) { serviceNode.setLabel(AndroidProjectResources.STRING_CALL_PREFIX + serviceLabel); } IntentFilterNode intentFilterNode = new IntentFilterNode(); if (intentFilterNode.getChildren().length > 0) { serviceNode.addIntentFilterNode(intentFilterNode); } applicationNode.addServiceNode(serviceNode); monitor.worked(1); monitor.subTask(CodeUtilsNLS.UI_Common_SavingTheAndroidManifestXMLFile); AndroidProjectManifestFile.saveToProject(getProject(), androidManifestFile, true); created = true; monitor.worked(1); } } } catch (AndroidException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_Service_CannotUpdateTheManifestFile, getName(), e.getLocalizedMessage()); throw new AndroidException(errMsg); } catch (CoreException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_Service_CannotUpdateTheManifestFile, getName(), e.getLocalizedMessage()); throw new AndroidException(errMsg); } finally { monitor.done(); } return created; } /* * Adds the Service label value on the strings resource file * * @param monitor The progress monitor * * @return The label value if it has been added to the strings resource file or null otherwise * @throws AndroidException */ private String createServiceLabel(IProgressMonitor monitor) throws AndroidException { String resLabel = null; if ((getLabel() != null) && (getLabel().trim().length() > 0)) { try { monitor.subTask(CodeUtilsNLS.UI_Common_UpdatingTheStringsResourceFile); ResourceFile stringsFile = AndroidProjectResources.getResourceFile(getProject(), NodeType.String); monitor.worked(1); if (stringsFile.getResourcesNode() == null) { stringsFile.addResourceEntry(new ResourcesNode()); } resLabel = stringsFile.getNewResourceName(getName() + SERVICE_RESOURCE_LABEL_SUFFIX); StringNode strNode = new StringNode(resLabel); strNode.setNodeValue(getLabel()); stringsFile.getResourcesNode().addChildNode(strNode); monitor.worked(1); AndroidProjectResources .saveResourceFile(getProject(), stringsFile, NodeType.String); monitor.worked(1); } catch (CoreException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_Service_CannotCreateTheServiceLabel, e.getLocalizedMessage()); throw new AndroidException(errMsg); } catch (AndroidException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_Service_CannotCreateTheServiceLabel, e.getLocalizedMessage()); throw new AndroidException(errMsg); } } return resLabel; } /** * @return True if the default onStart() method of the service class should be created. Otherwise, returns false. */ public boolean isOnStartMethod() { return onStartMethod; } /** * @param onStartMethod Set to true to have the default onStart() method of the service class automatically created. */ public void setOnStartMethod(boolean onStartMethod) { this.onStartMethod = onStartMethod; } /** * @return True if the default onCreate() method of the service class should be created. Otherwise, returns false. */ public boolean isOnCreateMethod() { return onCreateMethod; } /** * @param onStartMethod Set to true to have the default onCreate() method of the service class automatically created. */ public void setOnCreateMethod(boolean onCreateMethod) { this.onCreateMethod = onCreateMethod; } /** * @return The default onStart() method signature including return value and visibility level. */ public String getOnStartMessage() { final String ON_START_METHOD = "public void onStart(Intent intent, int startId)"; return ON_START_METHOD; //$NON-NLS-1$ } /** * @return The default onCreate() method signature including return value and visibility level. */ public String getOnCreateMessage() { final String ON_CREATE_METHOD = "public void onCreate()"; return ON_CREATE_METHOD; //$NON-NLS-1$ } }