# HG changeset patch # User Eugene Ostroukhov # Date 1265390360 28800 # Node ID 2196d1511a176a32bb6858e6dccda692d8ab81c5 # Parent b6d252d808df4abaf83c9f59ec0c62ea4a53c79b# Parent 024f49774fbbbe7d4d98a80d5f2ee35bd99e9797 Heads were merged diff -r b6d252d808df -r 2196d1511a17 org.symbian.tools.wrttools.product/launch/WRT IDE Product (Mac OS X).launch --- a/org.symbian.tools.wrttools.product/launch/WRT IDE Product (Mac OS X).launch Fri Feb 05 09:17:58 2010 -0800 +++ b/org.symbian.tools.wrttools.product/launch/WRT IDE Product (Mac OS X).launch Fri Feb 05 09:19:20 2010 -0800 @@ -1,4 +1,4 @@ - + @@ -21,8 +21,8 @@ - - + + diff -r b6d252d808df -r 2196d1511a17 org.symbian.tools.wrttools/.classpath --- a/org.symbian.tools.wrttools/.classpath Fri Feb 05 09:17:58 2010 -0800 +++ b/org.symbian.tools.wrttools/.classpath Fri Feb 05 09:19:20 2010 -0800 @@ -1,6 +1,6 @@ - + diff -r b6d252d808df -r 2196d1511a17 org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/internal/validation/WrtApplicationValidator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/internal/validation/WrtApplicationValidator.java Fri Feb 05 09:19:20 2010 -0800 @@ -0,0 +1,322 @@ +package org.symbian.tools.wrttools.core.internal.validation; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Set; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.text.IRegion; +import org.eclipse.wst.sse.core.StructuredModelManager; +import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; +import org.eclipse.wst.validation.AbstractValidator; +import org.eclipse.wst.validation.ValidationResult; +import org.eclipse.wst.validation.ValidationState; +import org.eclipse.wst.validation.ValidatorMessage; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; +import org.symbian.tools.wrttools.Activator; +import org.symbian.tools.wrttools.core.validator.ValidatorPropMessages; +import org.symbian.tools.wrttools.core.validator.PlistValidator.plistElements; +import org.symbian.tools.wrttools.util.CoreUtil; +import org.symbian.tools.wrttools.util.ProjectUtils; +import org.symbian.tools.wrttools.util.Util; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +@SuppressWarnings("restriction") +public class WrtApplicationValidator extends AbstractValidator { + @Override + public ValidationResult validate(IResource resource, int kind, + ValidationState state, IProgressMonitor monitor) { + if (ProjectUtils.isPlist(resource)) { + return validatePlist((IFile) resource); + } else if (isProject(resource)) { + return validateProject((IProject) resource); + } else { + return null; + } + } + + private ValidationResult validateProject(IProject resource) { + ValidationResult result = new ValidationResult(); + try { + isPlistPresent(resource, result); + } catch (CoreException e) { + Activator.log(e); + } + return result; + } + + private boolean isProject(IResource resource) { + return resource.getType() == IResource.PROJECT + && ProjectUtils.hasWrtNature(resource.getProject()); + } + + private ValidationResult validatePlist(IFile resource) { + ValidationResult result = new ValidationResult(); + IStructuredModel structuredModel; + try { + structuredModel = StructuredModelManager.getModelManager() + .getModelForRead(resource); + try { + if (structuredModel instanceof IDOMModel) { + IDOMModel model = (IDOMModel) structuredModel; + validateElement((IDOMElement) model.getDocument() + .getDocumentElement(), result, resource); + checkHtml(model, resource, result); + checkPlistValues(model, resource, result); + } + } finally { + if (structuredModel != null) { + structuredModel.releaseFromRead(); + } + } + } catch (IOException e) { + Activator.log(e); + } catch (CoreException e) { + Activator.log(e); + } + return result; + } + + private void validateElement(IDOMElement element, ValidationResult result, + IResource resource) { + // showData(""); + plistElements[] values = plistElements.values(); + boolean isValidElement = false; + for (plistElements validElement : values) { + if (validElement.toString().equalsIgnoreCase( + element.getNodeName().trim())) { + isValidElement = true; + break; + + } + continue; + } + if (!isValidElement) { + Object[] arguments = { " ", element.getNodeName().trim() }; + String message = MessageFormat.format(ValidatorPropMessages + .getString("plist.element.not.supported") + + "{0}" + "{1}", arguments); + result.add(createMessage(resource, message, element + .getStartOffset(), element.getEndOffset())); + } + + NodeList childNodes = element.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + if (item.getNodeType() == Node.ELEMENT_NODE) { + validateElement((IDOMElement) item, result, resource); + } + } + } + + private ValidatorMessage createMessage(IResource resource, String message, + int startOffset, int endOffset) { + ValidatorMessage msg = ValidatorMessage.create(message, resource); + msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + msg.setAttribute(IMarker.CHAR_START, startOffset); + msg.setAttribute(IMarker.CHAR_END, endOffset); + return msg; + } + + private boolean checkHtml(IDOMModel model, IFile plist, + ValidationResult result) { + String text = model.getStructuredDocument().get(); + IRegion region = CoreUtil.getIndexFileNameRegion(text); + boolean checkHtml = false; + if (region != null) { + String htmlName = text.substring(region.getOffset(), region + .getOffset() + + region.getLength()); + IFile htmlFile = null; + try { + htmlFile = getFile(plist.getProject(), new Path(htmlName), 0, + "html", "htm"); + } catch (CoreException e) { + Activator.log(e); + } + if (htmlFile == null) { + Object[] arguments = { htmlName, "<>", htmlName }; + String message = MessageFormat.format(ValidatorPropMessages + .getString("plist.html.element.mismatch") + + "{0}" + "{1}" + "{2}", arguments); + result.add(createMessage(plist, message, region.getOffset(), + region.getOffset() + region.getLength())); + } + } else { + String message = ValidatorPropMessages + .getString("plist.html.element.mailHtml.missing"); + ValidatorMessage msg = createMessage(plist, message, 0, 0); + setMessageOnRootElement(msg, model); + result.add(msg); + } + + return checkHtml; + } + + private void setMessageOnRootElement(ValidatorMessage msg, IDOMModel model) { + Element element = model.getDocument().getDocumentElement(); + int begin = 0, end = 0; + if (element instanceof IDOMNode) { + IDOMNode node = (IDOMNode) element; + begin = node.getStartOffset(); + end = node.getFirstStructuredDocumentRegion().getEnd(); + } + msg.setAttribute(IMarker.CHAR_START, begin); + msg.setAttribute(IMarker.CHAR_END, end); + } + + private IFile getFile(IContainer container, IPath path, int segment, + String... extensions) throws CoreException { + if (segment + 1 == path.segmentCount()) { + return getFile(container, path.lastSegment(), extensions); + } else { + String name = path.segment(segment).toLowerCase(); + IResource[] members = container.members(); + for (IResource resource : members) { + if (resource.getName().toLowerCase().equals(name)) { + if (resource.getType() == IResource.FOLDER) { + return getFile((IContainer) resource, path, + segment + 1, extensions); + } + } + } + } + return null; + } + + private IFile getFile(IContainer container, String lastSegment, + String[] extensions) throws CoreException { + final Set names = new TreeSet(); + names.add(lastSegment.toLowerCase()); + for (String extension : extensions) { + names.add(lastSegment.concat(".").concat(extension).toLowerCase()); + } + IResource[] members = container.members(); + for (IResource resource : members) { + if (resource.getType() == IResource.FILE + && names.contains(resource.getName().toLowerCase()) + && resource.isAccessible()) { + return (IFile) resource; + } + } + return null; + } + + private void checkPlistValues(IDOMModel model, IResource plist, + ValidationResult result) { + String source = model.getStructuredDocument().get(); + if (!hasAttributeValue(source, "DisplayName")) { + Object[] arguments = { " 'Display Name' ", + ValidatorPropMessages.getString("not.in.plist.file") }; + String message = MessageFormat.format(ValidatorPropMessages + .getString("plist.mankey.mising") + + "{0}" + "{1}", arguments); + ValidatorMessage msg = createMessage(plist, message, 0, 0); + setMessageOnRootElement(msg, model); + result.add(msg); + } else /* validating Widget name (Display name) */ + { + Matcher matcher = CoreUtil.getPropertyLookupPattern("DisplayName") + .matcher(source); + if (matcher.find()) { + String strError = Util.validateWidgetName(matcher.group(1)); + if (strError != null) { + Object[] arguments = { + " 'Display Name' ", + ValidatorPropMessages + .getString("contains.invalid.character") }; + String message = MessageFormat.format(ValidatorPropMessages + .getString("plist.mankey.mising") + + "{0}" + "{1}", arguments); + + ValidatorMessage msg = createMessage(plist, message, + matcher.start(), matcher.end()); + result.add(msg); + } + } + } + + if (!hasAttributeValue(source, "MainHTML")) { + Object[] arguments = { " 'MainHTML ' ", + ValidatorPropMessages.getString("not.in.plist.file") }; + String message = MessageFormat.format(ValidatorPropMessages + .getString("plist.mankey.mising") + + "{0}" + "{1}", arguments); + ValidatorMessage msg = createMessage(plist, message, 0, 0); + setMessageOnRootElement(msg, model); + result.add(msg); + } + if (!hasAttributeValue(source, "Identifier")) { + Object[] arguments = { " 'Identifier ' ", + ValidatorPropMessages.getString("not.in.plist.file") }; + String message = MessageFormat.format(ValidatorPropMessages + .getString("plist.mankey.mising") + + "{0}" + "{1}", arguments); + ValidatorMessage msg = createMessage(plist, message, 0, 0); + setMessageOnRootElement(msg, model); + result.add(msg); + } else /* validating Widget Idenfier (UID) */ + { + Matcher matcher = CoreUtil.getPropertyLookupPattern("Identifier") + .matcher(source); + if (matcher.find()) { + String strError = Util.validateWidgetID(matcher.group(1)); + if (strError != null) { + Object[] arguments = { + " 'Identifier' ", + ValidatorPropMessages + .getString("contains.invalid.character") }; + String message = MessageFormat.format(ValidatorPropMessages + .getString("plist.mankey.mising") + + "{0}" + "{1}", arguments); + + ValidatorMessage msg = createMessage(plist, message, + matcher.start(1), matcher.end(1)); + result.add(msg); + } + } + } + } + + private boolean hasAttributeValue(String source, String propertyName) { + Pattern pattern = CoreUtil.getPropertyLookupPattern(propertyName); + boolean hasAttr = true; + Matcher matcher = pattern.matcher(source); + if (!matcher.find()) { + hasAttr = false; + } else { + hasAttr = matcher.group(1).trim().length() > 0; + } + return hasAttr; + } + + private void isPlistPresent(IProject project, ValidationResult result) + throws CoreException { + IResource[] members = project.members(); + for (IResource resource : members) { + if (ProjectUtils.isPlist(resource)) { + return; + } + } + ValidatorMessage msg = ValidatorMessage.create(ValidatorPropMessages + .getString("plist.File.Not.Present"), project); + msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + + result.add(msg); + } +}