diff options
Diffstat (limited to 'src/plugins/preflighting.checkers/src/com/motorolamobility/preflighting/checkers/widgetPreview/MissingWidgetPreviewTagCondition.java')
-rw-r--r-- | src/plugins/preflighting.checkers/src/com/motorolamobility/preflighting/checkers/widgetPreview/MissingWidgetPreviewTagCondition.java | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/src/plugins/preflighting.checkers/src/com/motorolamobility/preflighting/checkers/widgetPreview/MissingWidgetPreviewTagCondition.java b/src/plugins/preflighting.checkers/src/com/motorolamobility/preflighting/checkers/widgetPreview/MissingWidgetPreviewTagCondition.java new file mode 100644 index 0000000..81251df --- /dev/null +++ b/src/plugins/preflighting.checkers/src/com/motorolamobility/preflighting/checkers/widgetPreview/MissingWidgetPreviewTagCondition.java @@ -0,0 +1,386 @@ +/* +* 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.motorolamobility.preflighting.checkers.widgetPreview; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.motorolamobility.preflighting.checkers.CheckerPlugin; +import com.motorolamobility.preflighting.checkers.i18n.CheckerNLS; +import com.motorolamobility.preflighting.core.applicationdata.ApplicationData; +import com.motorolamobility.preflighting.core.applicationdata.Element; +import com.motorolamobility.preflighting.core.applicationdata.Element.Type; +import com.motorolamobility.preflighting.core.applicationdata.ElementUtils; +import com.motorolamobility.preflighting.core.applicationdata.FolderElement; +import com.motorolamobility.preflighting.core.applicationdata.ResourcesFolderElement; +import com.motorolamobility.preflighting.core.applicationdata.XMLElement; +import com.motorolamobility.preflighting.core.checker.condition.CanExecuteConditionStatus; +import com.motorolamobility.preflighting.core.checker.condition.Condition; +import com.motorolamobility.preflighting.core.checker.condition.ICondition; +import com.motorolamobility.preflighting.core.devicespecification.DeviceSpecification; +import com.motorolamobility.preflighting.core.exception.PreflightingCheckerException; +import com.motorolamobility.preflighting.core.internal.cond.utils.ConditionUtils; +import com.motorolamobility.preflighting.core.utils.CheckerUtils; +import com.motorolamobility.preflighting.core.validation.ValidationManagerConfiguration; +import com.motorolamobility.preflighting.core.validation.ValidationResult; +import com.motorolamobility.preflighting.core.validation.ValidationResultData; + +public class MissingWidgetPreviewTagCondition extends Condition implements ICondition +{ + + /** + * + */ + private static final int MIN_TABLET_SDK_VERSION = 11; + + @Override + public void execute(ApplicationData data, List<DeviceSpecification> deviceSpecs, + ValidationManagerConfiguration valManagerConfig, ValidationResult results) + throws PreflightingCheckerException + { + ArrayList<ValidationResultData> resultDataList = new ArrayList<ValidationResultData>(); + + boolean hasTag = true; + + FolderElement xmlFolder = null; + XMLElement xmlFileElement = data.getManifestElement(); + + //Getting the sdk version, because only from android 3.0 on the previewImage is supported + String minSdkStr = CheckerUtils.getMinSdk(xmlFileElement.getDocument()); + int minSdkVersion = -1; + try + { + minSdkVersion = Integer.parseInt(minSdkStr); + } + catch (NumberFormatException e) + { + minSdkVersion = -1; + } + + //it only makes sense to check for previewImage in widgets applications + boolean isWidget = isWidgetAplication(data); + + //is a widget and is for android 3.0 and above version + if ((minSdkVersion >= MIN_TABLET_SDK_VERSION) && (isWidget)) + { + + xmlFolder = getXMLFolder(data); + //Get the xml filename responsible for the widget resources + ArrayList<String> xmlFilename = getWidgetResourceFilename(data); + + for (String resourceFile : xmlFilename) + { + ValidationResultData resultData = new ValidationResultData(); + //get the actual xml file element + xmlFileElement = getXMLFile(xmlFolder, resourceFile); + + //check for the android:previewImage tag + hasTag = checkForPreviewTag(xmlFileElement); + + if (hasTag) + { + //it is not a widget OR is not android 3.0+ version OR everything went fine + resultData.setSeverity(ValidationResultData.SEVERITY.OK); + + } + else + { + //start build the result + resultData.setSeverity(getSeverityLevel()); + resultData.setConditionID(getId()); + resultData.setInfoURL(ConditionUtils.getDescriptionLink(getChecker().getId(), + getId(), valManagerConfig)); + resultData + .setQuickFixSuggestion(CheckerNLS.MissingWidgetPreviewTagCondition_quickFix); + resultData + .setIssueDescription(CheckerNLS.MissingWidgetPreviewTagCondition_WarningMessage); + + resultData.addFileToIssueLines(xmlFileElement.getFile(), + Collections.<Integer> emptyList()); + + } + resultDataList.add(resultData); + + } + } + results.addAll(resultDataList); + + } + + @Override + public CanExecuteConditionStatus canExecute(ApplicationData data, + List<DeviceSpecification> deviceSpecs) throws PreflightingCheckerException + { + CanExecuteConditionStatus status = + new CanExecuteConditionStatus(IStatus.OK, CheckerPlugin.PLUGIN_ID, null); + status.setConditionId(getId()); + + XMLElement manElem = data.getManifestElement(); + if (manElem == null) + { + status = + new CanExecuteConditionStatus(IStatus.ERROR, CheckerPlugin.PLUGIN_ID, + CheckerNLS.Invalid_ManifestFile); + status.setConditionId(getId()); + } + else + { + Document manifestDoc = manElem.getDocument(); + + if (manifestDoc == null) + { + status = + new CanExecuteConditionStatus(IStatus.ERROR, CheckerPlugin.PLUGIN_ID, + CheckerNLS.Invalid_ManifestFile); + status.setConditionId(getId()); + } + } + + return status; + } + + /** + * This Method check for the widget related intent in order to determine if the application + * is a widget + * + * @param data + * @return whether the application is a widget project or not + * @throws PreflightingCheckerException + */ + + private boolean isWidgetAplication(ApplicationData data) throws PreflightingCheckerException + { + Boolean actionFound = false; + XMLElement manElem = data.getManifestElement(); + if (manElem != null) + { + Document manifestDoc = manElem.getDocument(); + if (manifestDoc != null) + { + NodeList rcvLst = manifestDoc.getElementsByTagName("receiver"); //$NON-NLS-1$ + + for (int receiverIndex = 0; receiverIndex < rcvLst.getLength(); receiverIndex++) + { + + NodeList intentFilterLst = rcvLst.item(receiverIndex).getChildNodes(); + for (int intentFilterIndex = 0; intentFilterIndex < intentFilterLst.getLength(); intentFilterIndex++) + { + Node intentFilterNode = intentFilterLst.item(intentFilterIndex); + // get intent-filter nodes + if (intentFilterNode.getNodeName().equals("intent-filter")) //$NON-NLS-1$ + { + NodeList actionLst = intentFilterNode.getChildNodes(); + for (int actionListIndex = 0; actionListIndex < actionLst.getLength(); actionListIndex++) + { + Node actionNode = actionLst.item(actionListIndex); + // get action nodes + if (actionNode.getNodeName().equals("action")) //$NON-NLS-1$ + { + NamedNodeMap map = actionNode.getAttributes(); + // name attribute must be set to + // android.appwidget.action.APPWIDGET_UPDATE + Node nameAtr = map.getNamedItem("android:name"); //$NON-NLS-1$ + + try + { + if ((nameAtr != null) + && nameAtr + .getNodeValue() + .equals("android.appwidget.action.APPWIDGET_UPDATE")) //$NON-NLS-1$ + { + actionFound = true; + + } + + } + catch (DOMException e) + { + // Error retrieving value of the action intent + throw new PreflightingCheckerException( + CheckerNLS.MainActivityChecker_Exception_Get_Action_Intent_Value, + e); + } + } + + } + + } + + } + } + } + } + return actionFound; + } + + /** + * This method retrieves the filename of the widget resouces XML pointed in the AndroidManifest + * @param data + * @return the filename + */ + + private ArrayList<String> getWidgetResourceFilename(ApplicationData data) + { + + ArrayList<String> xmlFilename = new ArrayList<String>(); + + XMLElement manElem = data.getManifestElement(); + if (manElem != null) + { + Document manifestDoc = manElem.getDocument(); + if (manifestDoc != null) + { + NodeList actLst = manifestDoc.getElementsByTagName("receiver"); //$NON-NLS-1$ + + for (int k = 0; k < actLst.getLength(); k++) + { + + NodeList intentFilterLst = actLst.item(k).getChildNodes(); + for (int j = 0; j < intentFilterLst.getLength(); j++) + { + Node metaDataNode = intentFilterLst.item(j); + // get meta-data + if (metaDataNode.getNodeName().equals("meta-data")) //$NON-NLS-1$ + { + + NamedNodeMap map = metaDataNode.getAttributes(); + // name attribute must be set to + // android.appwidget.provider + Node nameAtr = map.getNamedItem("android:name"); //$NON-NLS-1$ + + try + { + if ((nameAtr != null) + && nameAtr.getNodeValue().equals( + "android.appwidget.provider")) //$NON-NLS-1$ + { + Node resourceAtr = map.getNamedItem("android:resource"); //$NON-NLS-1$ + if (resourceAtr != null) + { + + xmlFilename.add(resourceAtr.getNodeValue() + .substring( + xmlFilename.indexOf("@xml/") + + "@xml/".length() + 1)); + + } + + } + + } + catch (DOMException e) + { + // DO Nothing + } + } + + } + + } + + } + } + return xmlFilename; //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * This method gets the xml folder of the project + * + * @param data + * @return the xml folder + */ + + private FolderElement getXMLFolder(ApplicationData data) + { + List<Element> folderResElements = + ElementUtils.getElementByType(data.getRootElement(), Type.FOLDER_RES); + FolderElement xmlFolder = null; + ResourcesFolderElement resFolder = + folderResElements.size() > 0 ? (ResourcesFolderElement) folderResElements.get(0) + : null; + + if (resFolder != null) + { + for (Element element : resFolder.getChildren()) + { + if ((element instanceof FolderElement) && (element.getName().equals("xml"))) //$NON-NLS-1$ + { + xmlFolder = (FolderElement) element; + } + } + } + return xmlFolder; + } + + private XMLElement getXMLFile(FolderElement xmlFolder, String xmlFilename) + { + XMLElement xmlFileElement = null; + if (xmlFolder instanceof FolderElement) + { + for (Element element : xmlFolder.getChildren()) + { + if (element.getName().equals(xmlFilename + ".xml") //$NON-NLS-1$ + && (element instanceof XMLElement)) + { + xmlFileElement = (XMLElement) element; + } + + } + } + return xmlFileElement; + } + + /** + * @param xmlFileElement + * @return + */ + private boolean checkForPreviewTag(XMLElement xmlFileElement) + { + boolean hasPreviewImage = false; + if (xmlFileElement != null) + { + Document resourceDoc = xmlFileElement.getDocument(); + if (resourceDoc != null) + { + NodeList provLst = resourceDoc.getElementsByTagName("appwidget-provider"); //$NON-NLS-1$ + + for (int k = 0; k < provLst.getLength(); k++) + { + + NamedNodeMap atrMap = provLst.item(k).getAttributes(); + Node previewImageNode = atrMap.getNamedItem("android:previewImage"); //$NON-NLS-1$ + + if (previewImageNode != null) + { + hasPreviewImage = true; + } + } + } + } + return hasPreviewImage; + + } + +} |