plugins/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/internal/validation/WrtApplicationValidator.java
changeset 484 f5df819c1852
parent 483 109da596fa9d
child 490 17d65127bce4
equal deleted inserted replaced
483:109da596fa9d 484:f5df819c1852
    34 import org.w3c.dom.Node;
    34 import org.w3c.dom.Node;
    35 import org.w3c.dom.NodeList;
    35 import org.w3c.dom.NodeList;
    36 
    36 
    37 @SuppressWarnings("restriction")
    37 @SuppressWarnings("restriction")
    38 public class WrtApplicationValidator extends AbstractValidator {
    38 public class WrtApplicationValidator extends AbstractValidator {
    39 	@Override
    39     @Override
    40 	public ValidationResult validate(IResource resource, int kind,
    40     public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) {
    41 			ValidationState state, IProgressMonitor monitor) {
    41         if (ProjectUtils.isPlist(resource)) {
    42 		if (ProjectUtils.isPlist(resource)) {
    42             return validatePlist((IFile) resource);
    43 			return validatePlist((IFile) resource);
    43         } else if (isProject(resource)) {
    44 		} else if (isProject(resource)) {
    44             return validateProject((IProject) resource);
    45 			return validateProject((IProject) resource);
    45         } else {
    46 		} else {
    46             return null;
    47 			return null;
    47         }
    48 		}
    48     }
    49 	}
    49 
    50 
    50     private ValidationResult validateProject(IProject resource) {
    51 	private ValidationResult validateProject(IProject resource) {
    51         ValidationResult result = new ValidationResult();
    52 		ValidationResult result = new ValidationResult();
    52         try {
    53 		try {
    53             isPlistPresent(resource, result);
    54 			isPlistPresent(resource, result);
    54         } catch (CoreException e) {
    55 		} catch (CoreException e) {
    55             Activator.log(e);
    56 			Activator.log(e);
    56         }
    57 		}
    57         return result;
    58 		return result;
    58     }
    59 	}
    59 
    60 
    60     private boolean isProject(IResource resource) {
    61 	private boolean isProject(IResource resource) {
    61         return resource.getType() == IResource.PROJECT && ProjectUtils.hasWrtNature(resource.getProject());
    62 		return resource.getType() == IResource.PROJECT
    62     }
    63 				&& ProjectUtils.hasWrtNature(resource.getProject());
    63 
    64 	}
    64     private ValidationResult validatePlist(IFile resource) {
    65 
    65         ValidationResult result = new ValidationResult();
    66 	private ValidationResult validatePlist(IFile resource) {
    66         IStructuredModel structuredModel;
    67 		ValidationResult result = new ValidationResult();
    67         try {
    68 		IStructuredModel structuredModel;
    68             structuredModel = StructuredModelManager.getModelManager().getModelForRead(resource);
    69 		try {
    69             try {
    70 			structuredModel = StructuredModelManager.getModelManager()
    70                 if (structuredModel instanceof IDOMModel) {
    71 					.getModelForRead(resource);
    71                     IDOMModel model = (IDOMModel) structuredModel;
    72 			try {
    72                     validateElement((IDOMElement) model.getDocument().getDocumentElement(), result, resource);
    73 				if (structuredModel instanceof IDOMModel) {
    73                     checkHtml(model, resource, result);
    74 					IDOMModel model = (IDOMModel) structuredModel;
    74                     checkPlistValues(model, resource, result);
    75 					validateElement((IDOMElement) model.getDocument()
    75                 }
    76 							.getDocumentElement(), result, resource);
    76             } finally {
    77 					checkHtml(model, resource, result);
    77                 if (structuredModel != null) {
    78 					checkPlistValues(model, resource, result);
    78                     structuredModel.releaseFromRead();
    79 				}
    79                 }
    80 			} finally {
    80             }
    81 				if (structuredModel != null) {
    81         } catch (IOException e) {
    82 					structuredModel.releaseFromRead();
    82             Activator.log(e);
    83 				}
    83         } catch (CoreException e) {
    84 			}
    84             Activator.log(e);
    85 		} catch (IOException e) {
    85         }
    86 			Activator.log(e);
    86         return result;
    87 		} catch (CoreException e) {
    87     }
    88 			Activator.log(e);
       
    89 		}
       
    90 		return result;
       
    91 	}
       
    92 
    88 
    93     private static enum PListElements {
    89     private static enum PListElements {
    94         plist, array, data, date, dict, real, integer, string, FALSE, TRUE, key, xml
    90         plist, array, data, date, dict, real, integer, string, FALSE, TRUE, key, xml
    95     };
    91     };
    96 
    92 
    97     private void validateElement(IDOMElement element, ValidationResult result,
    93     private void validateElement(IDOMElement element, ValidationResult result, IResource resource) {
    98 			IResource resource) {
    94         // showData("");
    99 		// showData("");
       
   100         PListElements[] values = PListElements.values();
    95         PListElements[] values = PListElements.values();
   101 		boolean isValidElement = false;
    96         boolean isValidElement = false;
   102         for (PListElements validElement : values) {
    97         for (PListElements validElement : values) {
   103 			if (validElement.toString().equalsIgnoreCase(
    98             if (validElement.toString().equalsIgnoreCase(element.getNodeName().trim())) {
   104 					element.getNodeName().trim())) {
    99                 isValidElement = true;
   105 				isValidElement = true;
   100                 break;
   106 				break;
   101 
   107 
   102             }
   108 			}
   103             continue;
   109 			continue;
   104         }
   110 		}
   105         if (!isValidElement) {
   111 		if (!isValidElement) {
   106             Object[] arguments = { "   ", element.getNodeName().trim() };
   112 			Object[] arguments = { "   ", element.getNodeName().trim() };
   107             String message = MessageFormat.format(ValidatorPropMessages.getString("plist.element.not.supported")
   113 			String message = MessageFormat.format(ValidatorPropMessages
   108                     + "{0}" + "{1}", arguments);
   114 					.getString("plist.element.not.supported")
   109             result.add(createMessage(resource, message, element.getStartOffset(), element.getEndOffset()));
   115 					+ "{0}" + "{1}", arguments);
   110         }
   116 			result.add(createMessage(resource, message, element
   111 
   117 					.getStartOffset(), element.getEndOffset()));
   112         NodeList childNodes = element.getChildNodes();
   118 		}
   113         for (int i = 0; i < childNodes.getLength(); i++) {
   119 
   114             Node item = childNodes.item(i);
   120 		NodeList childNodes = element.getChildNodes();
   115             if (item.getNodeType() == Node.ELEMENT_NODE) {
   121 		for (int i = 0; i < childNodes.getLength(); i++) {
   116                 validateElement((IDOMElement) item, result, resource);
   122 			Node item = childNodes.item(i);
   117             }
   123 			if (item.getNodeType() == Node.ELEMENT_NODE) {
   118         }
   124 				validateElement((IDOMElement) item, result, resource);
   119     }
   125 			}
   120 
   126 		}
   121     private ValidatorMessage createMessage(IResource resource, String message, int startOffset, int endOffset) {
   127 	}
   122         ValidatorMessage msg = ValidatorMessage.create(message, resource);
   128 
   123         msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
   129 	private ValidatorMessage createMessage(IResource resource, String message,
   124         msg.setAttribute(IMarker.CHAR_START, startOffset);
   130 			int startOffset, int endOffset) {
   125         msg.setAttribute(IMarker.CHAR_END, endOffset);
   131 		ValidatorMessage msg = ValidatorMessage.create(message, resource);
   126         return msg;
   132 		msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
   127     }
   133 		msg.setAttribute(IMarker.CHAR_START, startOffset);
   128 
   134 		msg.setAttribute(IMarker.CHAR_END, endOffset);
   129     private boolean checkHtml(IDOMModel model, IFile plist, ValidationResult result) {
   135 		return msg;
   130         String text = model.getStructuredDocument().get();
   136 	}
   131         IRegion region = CoreUtil.getIndexFileNameRegion(text);
   137 
   132         boolean checkHtml = false;
   138 	private boolean checkHtml(IDOMModel model, IFile plist,
   133         if (region != null) {
   139 			ValidationResult result) {
   134             String htmlName = text.substring(region.getOffset(), region.getOffset() + region.getLength());
   140 		String text = model.getStructuredDocument().get();
   135             IFile htmlFile = null;
   141 		IRegion region = CoreUtil.getIndexFileNameRegion(text);
   136             try {
   142 		boolean checkHtml = false;
   137                 htmlFile = getFile(plist.getProject(), new Path(htmlName), 0, "html", "htm");
   143 		if (region != null) {
   138             } catch (CoreException e) {
   144 			String htmlName = text.substring(region.getOffset(), region
   139                 Activator.log(e);
   145 					.getOffset()
   140             }
   146 					+ region.getLength());
   141             if (htmlFile == null) {
   147 			IFile htmlFile = null;
   142                 Object[] arguments = { htmlName, "<>", htmlName };
   148 			try {
   143                 String message = MessageFormat.format(ValidatorPropMessages.getString("plist.html.element.mismatch")
   149 				htmlFile = getFile(plist.getProject(), new Path(htmlName), 0,
   144                         + "{0}" + "{1}" + "{2}", arguments);
   150 						"html", "htm");
   145                 result.add(createMessage(plist, message, region.getOffset(), region.getOffset() + region.getLength()));
   151 			} catch (CoreException e) {
   146             }
   152 				Activator.log(e);
   147         } else {
   153 			}
   148             String message = ValidatorPropMessages.getString("plist.html.element.mailHtml.missing");
   154 			if (htmlFile == null) {
   149             ValidatorMessage msg = createMessage(plist, message, 0, 0);
   155 				Object[] arguments = { htmlName, "<>", htmlName };
   150             setMessageOnRootElement(msg, model);
   156 				String message = MessageFormat.format(ValidatorPropMessages
   151             result.add(msg);
   157 						.getString("plist.html.element.mismatch")
   152         }
   158 						+ "{0}" + "{1}" + "{2}", arguments);
   153 
   159 				result.add(createMessage(plist, message, region.getOffset(),
   154         return checkHtml;
   160 						region.getOffset() + region.getLength()));
   155     }
   161 			}
   156 
   162 		} else {
   157     private void setMessageOnRootElement(ValidatorMessage msg, IDOMModel model) {
   163 			String message = ValidatorPropMessages
   158         Element element = model.getDocument().getDocumentElement();
   164 					.getString("plist.html.element.mailHtml.missing");
   159         int begin = 0, end = 0;
   165 			ValidatorMessage msg = createMessage(plist, message, 0, 0);
   160         if (element instanceof IDOMNode) {
   166 			setMessageOnRootElement(msg, model);
   161             IDOMNode node = (IDOMNode) element;
   167 			result.add(msg);
   162             begin = node.getStartOffset();
   168 		}
   163             end = node.getFirstStructuredDocumentRegion().getEnd();
   169 
   164         }
   170 		return checkHtml;
   165         msg.setAttribute(IMarker.CHAR_START, begin);
   171 	}
   166         msg.setAttribute(IMarker.CHAR_END, end);
   172 
   167     }
   173 	private void setMessageOnRootElement(ValidatorMessage msg, IDOMModel model) {
   168 
   174 		Element element = model.getDocument().getDocumentElement();
   169     private IFile getFile(IContainer container, IPath path, int segment, String... extensions) throws CoreException {
   175 		int begin = 0, end = 0;
   170         if (segment + 1 == path.segmentCount()) {
   176 		if (element instanceof IDOMNode) {
   171             return getFile(container, path.lastSegment(), extensions);
   177 			IDOMNode node = (IDOMNode) element;
   172         } else {
   178 			begin = node.getStartOffset();
   173             String name = path.segment(segment).toLowerCase();
   179 			end = node.getFirstStructuredDocumentRegion().getEnd();
   174             IResource[] members = container.members();
   180 		}
   175             for (IResource resource : members) {
   181 		msg.setAttribute(IMarker.CHAR_START, begin);
   176                 if (resource.getName().toLowerCase().equals(name)) {
   182 		msg.setAttribute(IMarker.CHAR_END, end);
   177                     if (resource.getType() == IResource.FOLDER) {
   183 	}
   178                         return getFile((IContainer) resource, path, segment + 1, extensions);
   184 
   179                     }
   185 	private IFile getFile(IContainer container, IPath path, int segment,
   180                 }
   186 			String... extensions) throws CoreException {
   181             }
   187 		if (segment + 1 == path.segmentCount()) {
   182         }
   188 			return getFile(container, path.lastSegment(), extensions);
   183         return null;
   189 		} else {
   184     }
   190 			String name = path.segment(segment).toLowerCase();
   185 
   191 			IResource[] members = container.members();
   186     private IFile getFile(IContainer container, String lastSegment, String[] extensions) throws CoreException {
   192 			for (IResource resource : members) {
   187         final Set<String> names = new TreeSet<String>();
   193 				if (resource.getName().toLowerCase().equals(name)) {
   188         names.add(lastSegment.toLowerCase());
   194 					if (resource.getType() == IResource.FOLDER) {
   189         for (String extension : extensions) {
   195 						return getFile((IContainer) resource, path,
   190             names.add(lastSegment.concat(".").concat(extension).toLowerCase());
   196 								segment + 1, extensions);
   191         }
   197 					}
   192         IResource[] members = container.members();
   198 				}
   193         for (IResource resource : members) {
   199 			}
   194             if (resource.getType() == IResource.FILE && names.contains(resource.getName().toLowerCase())
   200 		}
   195                     && resource.isAccessible()) {
   201 		return null;
   196                 return (IFile) resource;
   202 	}
   197             }
   203 
   198         }
   204 	private IFile getFile(IContainer container, String lastSegment,
   199         return null;
   205 			String[] extensions) throws CoreException {
   200     }
   206 		final Set<String> names = new TreeSet<String>();
   201 
   207 		names.add(lastSegment.toLowerCase());
   202     private void checkPlistValues(IDOMModel model, IResource plist, ValidationResult result) {
   208 		for (String extension : extensions) {
   203         String source = model.getStructuredDocument().get();
   209 			names.add(lastSegment.concat(".").concat(extension).toLowerCase());
   204         if (!hasAttributeValue(source, "DisplayName")) {
   210 		}
   205             Object[] arguments = { " 'Display Name'  ", ValidatorPropMessages.getString("not.in.plist.file") };
   211 		IResource[] members = container.members();
   206             String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising") + "{0}"
   212 		for (IResource resource : members) {
   207                     + "{1}", arguments);
   213 			if (resource.getType() == IResource.FILE
   208             ValidatorMessage msg = createMessage(plist, message, 0, 0);
   214 					&& names.contains(resource.getName().toLowerCase())
   209             setMessageOnRootElement(msg, model);
   215 					&& resource.isAccessible()) {
   210             result.add(msg);
   216 				return (IFile) resource;
   211         } else { /* validating Widget name (Display name) */
   217 			}
   212             Matcher matcher = CoreUtil.getPropertyLookupPattern("DisplayName").matcher(source);
   218 		}
   213             if (matcher.find()) {
   219 		return null;
   214                 String strError = Util.validateWidgetName(matcher.group(1));
   220 	}
   215                 if (strError != null) {
   221 
   216                     Object[] arguments = { " 'Display Name'  ",
   222 	private void checkPlistValues(IDOMModel model, IResource plist,
   217                             ValidatorPropMessages.getString("contains.invalid.character") };
   223 			ValidationResult result) {
   218                     String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising")
   224 		String source = model.getStructuredDocument().get();
   219                             + "{0}" + "{1}", arguments);
   225 		if (!hasAttributeValue(source, "DisplayName")) {
   220 
   226 			Object[] arguments = { " 'Display Name'  ",
   221                     ValidatorMessage msg = createMessage(plist, message, matcher.start(), matcher.end());
   227 					ValidatorPropMessages.getString("not.in.plist.file") };
   222                     result.add(msg);
   228 			String message = MessageFormat.format(ValidatorPropMessages
   223                 }
   229 					.getString("plist.mankey.mising")
   224             }
   230 					+ "{0}" + "{1}", arguments);
   225         }
   231 			ValidatorMessage msg = createMessage(plist, message, 0, 0);
   226 
   232 			setMessageOnRootElement(msg, model);
   227         if (!hasAttributeValue(source, "MainHTML")) {
   233 			result.add(msg);
   228             Object[] arguments = { " 'MainHTML '  ", ValidatorPropMessages.getString("not.in.plist.file") };
   234 		} else /* validating Widget name (Display name) */
   229             String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising") + "{0}"
   235 		{
   230                     + "{1}", arguments);
   236 			Matcher matcher = CoreUtil.getPropertyLookupPattern("DisplayName")
   231             ValidatorMessage msg = createMessage(plist, message, 0, 0);
   237 					.matcher(source);
   232             setMessageOnRootElement(msg, model);
   238 			if (matcher.find()) {
   233             result.add(msg);
   239 				String strError = Util.validateWidgetName(matcher.group(1));
   234         }
   240 				if (strError != null) {
   235         if (!hasAttributeValue(source, "Identifier")) {
   241 					Object[] arguments = {
   236             Object[] arguments = { " 'Identifier '  ", ValidatorPropMessages.getString("not.in.plist.file") };
   242 							" 'Display Name'  ",
   237             String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising") + "{0}"
   243 							ValidatorPropMessages
   238                     + "{1}", arguments);
   244 									.getString("contains.invalid.character") };
   239             ValidatorMessage msg = createMessage(plist, message, 0, 0);
   245 					String message = MessageFormat.format(ValidatorPropMessages
   240             setMessageOnRootElement(msg, model);
   246 							.getString("plist.mankey.mising")
   241             result.add(msg);
   247 							+ "{0}" + "{1}", arguments);
   242         } else { /* validating Widget Idenfier (UID) */
   248 
   243             Matcher matcher = CoreUtil.getPropertyLookupPattern("Identifier").matcher(source);
   249 					ValidatorMessage msg = createMessage(plist, message,
   244             if (matcher.find()) {
   250 							matcher.start(), matcher.end());
   245                 String strError = Util.validateWidgetID(matcher.group(1));
   251 					result.add(msg);
   246                 if (strError != null) {
   252 				}
   247                     Object[] arguments = { " 'Identifier'  ",
   253 			}
   248                             ValidatorPropMessages.getString("contains.invalid.character") };
   254 		}
   249                     String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising")
   255 
   250                             + "{0}" + "{1}", arguments);
   256 		if (!hasAttributeValue(source, "MainHTML")) {
   251 
   257 			Object[] arguments = { " 'MainHTML '  ",
   252                     ValidatorMessage msg = createMessage(plist, message, matcher.start(1), matcher.end(1));
   258 					ValidatorPropMessages.getString("not.in.plist.file") };
   253                     result.add(msg);
   259 			String message = MessageFormat.format(ValidatorPropMessages
   254                 }
   260 					.getString("plist.mankey.mising")
   255             }
   261 					+ "{0}" + "{1}", arguments);
   256         }
   262 			ValidatorMessage msg = createMessage(plist, message, 0, 0);
   257     }
   263 			setMessageOnRootElement(msg, model);
   258 
   264 			result.add(msg);
   259     private boolean hasAttributeValue(String source, String propertyName) {
   265 		}
   260         Pattern pattern = CoreUtil.getPropertyLookupPattern(propertyName);
   266 		if (!hasAttributeValue(source, "Identifier")) {
   261         boolean hasAttr = true;
   267 			Object[] arguments = { " 'Identifier '  ",
   262         Matcher matcher = pattern.matcher(source);
   268 					ValidatorPropMessages.getString("not.in.plist.file") };
   263         if (!matcher.find()) {
   269 			String message = MessageFormat.format(ValidatorPropMessages
   264             hasAttr = false;
   270 					.getString("plist.mankey.mising")
   265         } else {
   271 					+ "{0}" + "{1}", arguments);
   266             hasAttr = matcher.group(1).trim().length() > 0;
   272 			ValidatorMessage msg = createMessage(plist, message, 0, 0);
   267         }
   273 			setMessageOnRootElement(msg, model);
   268         return hasAttr;
   274 			result.add(msg);
   269     }
   275 		} else /* validating Widget Idenfier (UID) */
   270 
   276 		{
   271     private void isPlistPresent(IProject project, ValidationResult result) throws CoreException {
   277 			Matcher matcher = CoreUtil.getPropertyLookupPattern("Identifier")
   272         IResource[] members = project.members();
   278 					.matcher(source);
   273         for (IResource resource : members) {
   279 			if (matcher.find()) {
   274             if (ProjectUtils.isPlist(resource)) {
   280 				String strError = Util.validateWidgetID(matcher.group(1));
   275                 return;
   281 				if (strError != null) {
   276             }
   282 					Object[] arguments = {
   277         }
   283 							" 'Identifier'  ",
   278         ValidatorMessage msg = ValidatorMessage.create(ValidatorPropMessages.getString("plist.File.Not.Present"),
   284 							ValidatorPropMessages
   279                 project);
   285 									.getString("contains.invalid.character") };
   280         msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
   286 					String message = MessageFormat.format(ValidatorPropMessages
   281 
   287 							.getString("plist.mankey.mising")
   282         result.add(msg);
   288 							+ "{0}" + "{1}", arguments);
   283     }
   289 
       
   290 					ValidatorMessage msg = createMessage(plist, message,
       
   291 							matcher.start(1), matcher.end(1));
       
   292 					result.add(msg);
       
   293 				}
       
   294 			}
       
   295 		}
       
   296 	}
       
   297 
       
   298 	private boolean hasAttributeValue(String source, String propertyName) {
       
   299 		Pattern pattern = CoreUtil.getPropertyLookupPattern(propertyName);
       
   300 		boolean hasAttr = true;
       
   301 		Matcher matcher = pattern.matcher(source);
       
   302 		if (!matcher.find()) {
       
   303 			hasAttr = false;
       
   304 		} else {
       
   305 			hasAttr = matcher.group(1).trim().length() > 0;
       
   306 		}
       
   307 		return hasAttr;
       
   308 	}
       
   309 
       
   310 	private void isPlistPresent(IProject project, ValidationResult result)
       
   311 			throws CoreException {
       
   312 		IResource[] members = project.members();
       
   313 		for (IResource resource : members) {
       
   314 			if (ProjectUtils.isPlist(resource)) {
       
   315 				return;
       
   316 			}
       
   317 		}
       
   318 		ValidatorMessage msg = ValidatorMessage.create(ValidatorPropMessages
       
   319 				.getString("plist.File.Not.Present"), project);
       
   320 		msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
       
   321 
       
   322 		result.add(msg);
       
   323 	}
       
   324 }
   284 }