Lines 10-20
Link Here
|
10 |
*******************************************************************************/ |
10 |
*******************************************************************************/ |
11 |
package org.eclipse.jdt.internal.core; |
11 |
package org.eclipse.jdt.internal.core; |
12 |
|
12 |
|
|
|
13 |
import java.io.CharArrayWriter; |
13 |
import java.io.File; |
14 |
import java.io.File; |
|
|
15 |
import java.io.IOException; |
16 |
import java.util.ArrayList; |
14 |
import java.util.HashMap; |
17 |
import java.util.HashMap; |
15 |
import java.util.HashSet; |
18 |
import java.util.HashSet; |
16 |
import java.util.Map; |
19 |
import java.util.Map; |
17 |
|
20 |
|
|
|
21 |
import org.apache.crimson.tree.XmlWritable; |
22 |
import org.apache.crimson.tree.XmlWriteContext; |
18 |
import org.eclipse.core.resources.IProject; |
23 |
import org.eclipse.core.resources.IProject; |
19 |
import org.eclipse.core.resources.IResource; |
24 |
import org.eclipse.core.resources.IResource; |
20 |
import org.eclipse.core.resources.IWorkspaceRoot; |
25 |
import org.eclipse.core.resources.IWorkspaceRoot; |
Lines 39-45
Link Here
|
39 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
44 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
40 |
import org.eclipse.jdt.internal.core.util.Messages; |
45 |
import org.eclipse.jdt.internal.core.util.Messages; |
41 |
import org.eclipse.jdt.internal.core.util.Util; |
46 |
import org.eclipse.jdt.internal.core.util.Util; |
|
|
47 |
import org.w3c.dom.DOMException; |
42 |
import org.w3c.dom.Element; |
48 |
import org.w3c.dom.Element; |
|
|
49 |
import org.w3c.dom.NamedNodeMap; |
43 |
import org.w3c.dom.Node; |
50 |
import org.w3c.dom.Node; |
44 |
import org.w3c.dom.NodeList; |
51 |
import org.w3c.dom.NodeList; |
45 |
|
52 |
|
Lines 119-124
Link Here
|
119 |
private String rootID; |
126 |
private String rootID; |
120 |
private AccessRuleSet accessRuleSet; |
127 |
private AccessRuleSet accessRuleSet; |
121 |
|
128 |
|
|
|
129 |
private String[] unknownAttributes; |
130 |
private ArrayList unknownChildren; |
131 |
|
122 |
/* |
132 |
/* |
123 |
* Default inclusion pattern set |
133 |
* Default inclusion pattern set |
124 |
*/ |
134 |
*/ |
Lines 278-287
Link Here
|
278 |
return result; |
288 |
return result; |
279 |
} |
289 |
} |
280 |
|
290 |
|
281 |
static IClasspathAttribute[] decodeExtraAttributes(Element element) { |
291 |
static IClasspathAttribute[] decodeExtraAttributes(NodeList attributes) { |
282 |
Node extra = element.getElementsByTagName(TAG_ATTRIBUTES).item(0); |
|
|
283 |
if (extra == null) return NO_EXTRA_ATTRIBUTES; |
284 |
NodeList attributes = element.getElementsByTagName(TAG_ATTRIBUTE); |
285 |
if (attributes == null) return NO_EXTRA_ATTRIBUTES; |
292 |
if (attributes == null) return NO_EXTRA_ATTRIBUTES; |
286 |
int length = attributes.getLength(); |
293 |
int length = attributes.getLength(); |
287 |
if (length == 0) return NO_EXTRA_ATTRIBUTES; |
294 |
if (length == 0) return NO_EXTRA_ATTRIBUTES; |
Lines 303-333
Link Here
|
303 |
return result; |
310 |
return result; |
304 |
} |
311 |
} |
305 |
|
312 |
|
306 |
static IAccessRule[] decodeAccessRules(Element element) { |
313 |
static IAccessRule[] decodeAccessRules(NodeList list) { |
307 |
Node accessRules = element.getElementsByTagName(TAG_ACCESS_RULES).item(0); |
314 |
if (list == null) return null; |
308 |
if (accessRules == null || accessRules.getNodeType() != Node.ELEMENT_NODE) return null; |
|
|
309 |
NodeList list = ((Element) accessRules).getElementsByTagName(TAG_ACCESS_RULE); |
310 |
int length = list.getLength(); |
315 |
int length = list.getLength(); |
311 |
if (length == 0) return null; |
316 |
if (length == 0) return null; |
312 |
IAccessRule[] result = new IAccessRule[length]; |
317 |
IAccessRule[] result = new IAccessRule[length]; |
313 |
int index = 0; |
318 |
int index = 0; |
314 |
for (int i = 0; i < length; i++) { |
319 |
for (int i = 0; i < length; i++) { |
315 |
Node accessRule = list.item(i); |
320 |
Node accessRule = list.item(i); |
316 |
if (accessRule == null || accessRule.getNodeType() != Node.ELEMENT_NODE) return null; |
321 |
if (accessRule.getNodeType() == Node.ELEMENT_NODE) { |
317 |
Element elementAccessRule = (Element) accessRule; |
322 |
Element elementAccessRule = (Element) accessRule; |
318 |
String pattern = elementAccessRule.getAttribute(TAG_PATTERN); |
323 |
String pattern = elementAccessRule.getAttribute(TAG_PATTERN); |
319 |
if (pattern == null) continue; |
324 |
if (pattern == null) continue; |
320 |
String tagKind = elementAccessRule.getAttribute(TAG_KIND); |
325 |
String tagKind = elementAccessRule.getAttribute(TAG_KIND); |
321 |
int kind; |
326 |
int kind; |
322 |
if (TAG_ACCESSIBLE.equals(tagKind)) |
327 |
if (TAG_ACCESSIBLE.equals(tagKind)) |
323 |
kind = IAccessRule.K_ACCESSIBLE; |
328 |
kind = IAccessRule.K_ACCESSIBLE; |
324 |
else if (TAG_NON_ACCESSIBLE.equals(tagKind)) |
329 |
else if (TAG_NON_ACCESSIBLE.equals(tagKind)) |
325 |
kind = IAccessRule.K_NON_ACCESSIBLE; |
330 |
kind = IAccessRule.K_NON_ACCESSIBLE; |
326 |
else if (TAG_DISCOURAGED.equals(tagKind)) |
331 |
else if (TAG_DISCOURAGED.equals(tagKind)) |
327 |
kind = IAccessRule.K_DISCOURAGED; |
332 |
kind = IAccessRule.K_DISCOURAGED; |
328 |
else |
333 |
else |
329 |
continue; |
334 |
continue; |
330 |
result[index++] = new ClasspathAccessRule(new Path(pattern), kind); |
335 |
result[index++] = new ClasspathAccessRule(new Path(pattern), kind); |
|
|
336 |
} |
331 |
} |
337 |
} |
332 |
if (index != length) |
338 |
if (index != length) |
333 |
System.arraycopy(result, 0, result = new IAccessRule[index], 0, index); |
339 |
System.arraycopy(result, 0, result = new IAccessRule[index], 0, index); |
Lines 337-344
Link Here
|
337 |
/** |
343 |
/** |
338 |
* Decode some element tag containing a sequence of patterns into IPath[] |
344 |
* Decode some element tag containing a sequence of patterns into IPath[] |
339 |
*/ |
345 |
*/ |
340 |
private static IPath[] decodePatterns(Element element, String tag) { |
346 |
private static IPath[] decodePatterns(NamedNodeMap nodeMap, String tag) { |
341 |
String sequence = element.getAttribute(tag); |
347 |
String sequence = removeAttribute(tag, nodeMap); |
342 |
if (!sequence.equals("")) { //$NON-NLS-1$ |
348 |
if (!sequence.equals("")) { //$NON-NLS-1$ |
343 |
char[][] patterns = CharOperation.splitOn('|', sequence.toCharArray()); |
349 |
char[][] patterns = CharOperation.splitOn('|', sequence.toCharArray()); |
344 |
int patternCount; |
350 |
int patternCount; |
Lines 352-357
Link Here
|
352 |
} |
358 |
} |
353 |
return null; |
359 |
return null; |
354 |
} |
360 |
} |
|
|
361 |
|
362 |
private static void decodeUnknownChild(Node child, StringBuffer buffer) { |
363 |
if (child instanceof XmlWritable) { |
364 |
CharArrayWriter writer = new CharArrayWriter(); |
365 |
XmlWriteContext context = new XmlWriteContext(writer); |
366 |
try { |
367 |
((XmlWritable) child).writeXml(context); |
368 |
buffer.append(writer.toString()); |
369 |
} catch (IOException e) { |
370 |
buffer.append("<exception reading unknown elements (see previous version from local history)>"); //$NON-NLS-1$ |
371 |
} |
372 |
} else { |
373 |
buffer.append("<unknown elements detected (see previous version from local history)>"); //$NON-NLS-1$ |
374 |
} |
375 |
} |
376 |
|
355 |
/* |
377 |
/* |
356 |
* Returns a char based representation of the exclusions patterns full path. |
378 |
* Returns a char based representation of the exclusions patterns full path. |
357 |
*/ |
379 |
*/ |
Lines 432-437
Link Here
|
432 |
if (this.entryKind == CPE_PROJECT && !this.combineAccessRules) |
454 |
if (this.entryKind == CPE_PROJECT && !this.combineAccessRules) |
433 |
parameters.put(TAG_COMBINE_ACCESS_RULES, "false"); //$NON-NLS-1$ |
455 |
parameters.put(TAG_COMBINE_ACCESS_RULES, "false"); //$NON-NLS-1$ |
434 |
|
456 |
|
|
|
457 |
// unknown attributes |
458 |
if (this.unknownAttributes != null) |
459 |
for (int i = 0, length = this.unknownAttributes.length; i < length; i+=2) { |
460 |
String tagName = this.unknownAttributes[i]; |
461 |
String tagValue = this.unknownAttributes[i+1]; |
462 |
parameters.put(tagName, tagValue); |
463 |
} |
435 |
|
464 |
|
436 |
if (this.specificOutputLocation != null) { |
465 |
if (this.specificOutputLocation != null) { |
437 |
IPath outputLocation = this.specificOutputLocation.removeFirstSegments(1); |
466 |
IPath outputLocation = this.specificOutputLocation.removeFirstSegments(1); |
Lines 441-455
Link Here
|
441 |
|
470 |
|
442 |
boolean hasExtraAttributes = this.extraAttributes.length != 0; |
471 |
boolean hasExtraAttributes = this.extraAttributes.length != 0; |
443 |
boolean hasRestrictions = getAccessRuleSet() != null; // access rule set is null if no access rules |
472 |
boolean hasRestrictions = getAccessRuleSet() != null; // access rule set is null if no access rules |
444 |
writer.printTag(TAG_CLASSPATHENTRY, parameters, indent, newLine, !hasExtraAttributes && !hasRestrictions /*close tag if no extra attributes and no restriction*/); |
473 |
boolean hasUnknownChildren = this.unknownChildren != null; |
|
|
474 |
writer.printTag( |
475 |
TAG_CLASSPATHENTRY, |
476 |
parameters, |
477 |
indent, |
478 |
newLine, |
479 |
!hasExtraAttributes && !hasRestrictions && !hasUnknownChildren/*close tag if no extra attributes, no restriction and no unknown children*/); |
445 |
|
480 |
|
446 |
if (hasExtraAttributes) |
481 |
if (hasExtraAttributes) |
447 |
encodeExtraAttributes(writer, indent, newLine); |
482 |
encodeExtraAttributes(writer, indent, newLine); |
448 |
|
483 |
|
449 |
if (hasRestrictions) |
484 |
if (hasRestrictions) |
450 |
encodeAccessRules(writer, indent, newLine); |
485 |
encodeAccessRules(writer, indent, newLine); |
|
|
486 |
|
487 |
if (hasUnknownChildren) |
488 |
encodeUnknownChildren(writer, indent, newLine); |
451 |
|
489 |
|
452 |
if (hasExtraAttributes || hasRestrictions) |
490 |
if (hasExtraAttributes || hasRestrictions || hasUnknownChildren) |
453 |
writer.endTag(TAG_CLASSPATHENTRY, indent); |
491 |
writer.endTag(TAG_CLASSPATHENTRY, indent); |
454 |
} |
492 |
} |
455 |
|
493 |
|
Lines 496-506
Link Here
|
496 |
|
534 |
|
497 |
} |
535 |
} |
498 |
|
536 |
|
|
|
537 |
private void encodeUnknownChildren(XMLWriter writer, boolean indent, boolean newLine) { |
538 |
for (int i = 0, length = this.unknownChildren.size(); i < length; i++) { |
539 |
String child = (String) this.unknownChildren.get(i); |
540 |
writer.printString(child, indent, newLine); |
541 |
} |
542 |
} |
543 |
|
499 |
public static IClasspathEntry elementDecode(Element element, IJavaProject project) { |
544 |
public static IClasspathEntry elementDecode(Element element, IJavaProject project) { |
500 |
|
545 |
|
501 |
IPath projectPath = project.getProject().getFullPath(); |
546 |
IPath projectPath = project.getProject().getFullPath(); |
502 |
String kindAttr = element.getAttribute(TAG_KIND); |
547 |
NamedNodeMap attributes = element.getAttributes(); |
503 |
String pathAttr = element.getAttribute(TAG_PATH); |
548 |
NodeList children = element.getChildNodes(); |
|
|
549 |
boolean[] foundChildren = new boolean[children.getLength()]; |
550 |
String kindAttr = removeAttribute(TAG_KIND, attributes); |
551 |
String pathAttr = removeAttribute(TAG_PATH, attributes); |
504 |
|
552 |
|
505 |
// ensure path is absolute |
553 |
// ensure path is absolute |
506 |
IPath path = new Path(pathAttr); |
554 |
IPath path = new Path(pathAttr); |
Lines 511-539
Link Here
|
511 |
// source attachment info (optional) |
559 |
// source attachment info (optional) |
512 |
IPath sourceAttachmentPath = |
560 |
IPath sourceAttachmentPath = |
513 |
element.hasAttribute(TAG_SOURCEPATH) |
561 |
element.hasAttribute(TAG_SOURCEPATH) |
514 |
? new Path(element.getAttribute(TAG_SOURCEPATH)) |
562 |
? new Path(removeAttribute(TAG_SOURCEPATH, attributes)) |
515 |
: null; |
563 |
: null; |
516 |
if (kind != IClasspathEntry.CPE_VARIABLE && sourceAttachmentPath != null && !sourceAttachmentPath.isAbsolute()) { |
564 |
if (kind != IClasspathEntry.CPE_VARIABLE && sourceAttachmentPath != null && !sourceAttachmentPath.isAbsolute()) { |
517 |
sourceAttachmentPath = projectPath.append(sourceAttachmentPath); |
565 |
sourceAttachmentPath = projectPath.append(sourceAttachmentPath); |
518 |
} |
566 |
} |
519 |
IPath sourceAttachmentRootPath = |
567 |
IPath sourceAttachmentRootPath = |
520 |
element.hasAttribute(TAG_ROOTPATH) |
568 |
element.hasAttribute(TAG_ROOTPATH) |
521 |
? new Path(element.getAttribute(TAG_ROOTPATH)) |
569 |
? new Path(removeAttribute(TAG_ROOTPATH, attributes)) |
522 |
: null; |
570 |
: null; |
523 |
|
571 |
|
524 |
// exported flag (optional) |
572 |
// exported flag (optional) |
525 |
boolean isExported = element.getAttribute(TAG_EXPORTED).equals("true"); //$NON-NLS-1$ |
573 |
boolean isExported = removeAttribute(TAG_EXPORTED, attributes).equals("true"); //$NON-NLS-1$ |
526 |
|
574 |
|
527 |
// inclusion patterns (optional) |
575 |
// inclusion patterns (optional) |
528 |
IPath[] inclusionPatterns = decodePatterns(element, TAG_INCLUDING); |
576 |
IPath[] inclusionPatterns = decodePatterns(attributes, TAG_INCLUDING); |
529 |
if (inclusionPatterns == null) inclusionPatterns = INCLUDE_ALL; |
577 |
if (inclusionPatterns == null) inclusionPatterns = INCLUDE_ALL; |
530 |
|
578 |
|
531 |
// exclusion patterns (optional) |
579 |
// exclusion patterns (optional) |
532 |
IPath[] exclusionPatterns = decodePatterns(element, TAG_EXCLUDING); |
580 |
IPath[] exclusionPatterns = decodePatterns(attributes, TAG_EXCLUDING); |
533 |
if (exclusionPatterns == null) exclusionPatterns = EXCLUDE_NONE; |
581 |
if (exclusionPatterns == null) exclusionPatterns = EXCLUDE_NONE; |
534 |
|
582 |
|
535 |
// access rules (optional) |
583 |
// access rules (optional) |
536 |
IAccessRule[] accessRules = decodeAccessRules(element); |
584 |
NodeList attributeList = getChildAttributes(TAG_ACCESS_RULES, children, foundChildren); |
|
|
585 |
IAccessRule[] accessRules = decodeAccessRules(attributeList); |
537 |
|
586 |
|
538 |
// backward compatibility |
587 |
// backward compatibility |
539 |
if (accessRules == null) { |
588 |
if (accessRules == null) { |
Lines 541-553
Link Here
|
541 |
} |
590 |
} |
542 |
|
591 |
|
543 |
// combine access rules (optional) |
592 |
// combine access rules (optional) |
544 |
boolean combineAccessRestrictions = !element.getAttribute(TAG_COMBINE_ACCESS_RULES).equals("false"); //$NON-NLS-1$ |
593 |
boolean combineAccessRestrictions = !removeAttribute(TAG_COMBINE_ACCESS_RULES, attributes).equals("false"); //$NON-NLS-1$ |
545 |
|
594 |
|
546 |
// extra attributes (optional) |
595 |
// extra attributes (optional) |
547 |
IClasspathAttribute[] extraAttributes = decodeExtraAttributes(element); |
596 |
attributeList = getChildAttributes(TAG_ATTRIBUTES, children, foundChildren); |
|
|
597 |
IClasspathAttribute[] extraAttributes = decodeExtraAttributes(attributeList); |
548 |
|
598 |
|
549 |
// custom output location |
599 |
// custom output location |
550 |
IPath outputLocation = element.hasAttribute(TAG_OUTPUT) ? projectPath.append(element.getAttribute(TAG_OUTPUT)) : null; |
600 |
IPath outputLocation = element.hasAttribute(TAG_OUTPUT) ? projectPath.append(removeAttribute(TAG_OUTPUT, attributes)) : null; |
|
|
601 |
|
602 |
// unknown attributes |
603 |
String[] unknownAttributes = null; |
604 |
int unknownAttributeLength = attributes.getLength(); |
605 |
if (unknownAttributeLength != 0) { |
606 |
unknownAttributes = new String[unknownAttributeLength*2]; |
607 |
for (int i = 0; i < unknownAttributeLength; i++) { |
608 |
Node attribute = attributes.item(i); |
609 |
unknownAttributes[i*2] = attribute.getNodeName(); |
610 |
unknownAttributes[i*2 + 1] = attribute.getNodeValue(); |
611 |
} |
612 |
} |
613 |
|
614 |
// unknown children |
615 |
ArrayList unknownChildren = null; |
616 |
for (int i = 0, length = foundChildren.length; i < length; i++) { |
617 |
if (!foundChildren[i]) { |
618 |
Node node = children.item(i); |
619 |
if (node.getNodeType() != Node.ELEMENT_NODE) continue; |
620 |
if (unknownChildren == null) |
621 |
unknownChildren = new ArrayList(); |
622 |
StringBuffer buffer = new StringBuffer(); |
623 |
decodeUnknownChild(node, buffer); |
624 |
unknownChildren.add(buffer.toString()); |
625 |
} |
626 |
} |
551 |
|
627 |
|
552 |
// recreate the CP entry |
628 |
// recreate the CP entry |
553 |
IClasspathEntry entry = null; |
629 |
IClasspathEntry entry = null; |
Lines 574-580
Link Here
|
574 |
// must be an entry in this project or specify another project |
650 |
// must be an entry in this project or specify another project |
575 |
String projSegment = path.segment(0); |
651 |
String projSegment = path.segment(0); |
576 |
if (projSegment != null && projSegment.equals(project.getElementName())) { // this project |
652 |
if (projSegment != null && projSegment.equals(project.getElementName())) { // this project |
577 |
return JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation, extraAttributes); |
653 |
entry = JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation, extraAttributes); |
578 |
} else { |
654 |
} else { |
579 |
if (path.segmentCount() == 1) { |
655 |
if (path.segmentCount() == 1) { |
580 |
// another project |
656 |
// another project |
Lines 586-592
Link Here
|
586 |
isExported); |
662 |
isExported); |
587 |
} else { |
663 |
} else { |
588 |
// an invalid source folder |
664 |
// an invalid source folder |
589 |
return JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation, extraAttributes); |
665 |
entry = JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation, extraAttributes); |
590 |
} |
666 |
} |
591 |
} |
667 |
} |
592 |
break; |
668 |
break; |
Lines 608-614
Link Here
|
608 |
break; |
684 |
break; |
609 |
case ClasspathEntry.K_OUTPUT : |
685 |
case ClasspathEntry.K_OUTPUT : |
610 |
if (!path.isAbsolute()) return null; |
686 |
if (!path.isAbsolute()) return null; |
611 |
return new ClasspathEntry( |
687 |
entry = new ClasspathEntry( |
612 |
ClasspathEntry.K_OUTPUT, |
688 |
ClasspathEntry.K_OUTPUT, |
613 |
IClasspathEntry.CPE_LIBRARY, |
689 |
IClasspathEntry.CPE_LIBRARY, |
614 |
path, |
690 |
path, |
Lines 621-631
Link Here
|
621 |
null, // no access rules |
697 |
null, // no access rules |
622 |
false, // no accessible files to combine |
698 |
false, // no accessible files to combine |
623 |
NO_EXTRA_ATTRIBUTES); |
699 |
NO_EXTRA_ATTRIBUTES); |
|
|
700 |
break; |
624 |
default : |
701 |
default : |
625 |
throw new Assert.AssertionFailedException(Messages.bind(Messages.classpath_unknownKind, kindAttr)); |
702 |
throw new Assert.AssertionFailedException(Messages.bind(Messages.classpath_unknownKind, kindAttr)); |
626 |
} |
703 |
} |
|
|
704 |
|
705 |
ClasspathEntry classpathEntry = (ClasspathEntry) entry; |
706 |
classpathEntry.unknownAttributes = unknownAttributes; |
707 |
classpathEntry.unknownChildren = unknownChildren; |
708 |
|
627 |
return entry; |
709 |
return entry; |
628 |
} |
710 |
} |
|
|
711 |
|
712 |
public static NodeList getChildAttributes(String childName, NodeList children, boolean[] foundChildren) { |
713 |
for (int i = 0, length = foundChildren.length; i < length; i++) { |
714 |
Node node = children.item(i); |
715 |
if (childName.equals(node.getNodeName())) { |
716 |
foundChildren[i] = true; |
717 |
return node.getChildNodes(); |
718 |
} |
719 |
} |
720 |
return null; |
721 |
} |
722 |
|
723 |
|
724 |
private static String removeAttribute(String nodeName, NamedNodeMap nodeMap) { |
725 |
Node node = removeNode(nodeName, nodeMap); |
726 |
if (node == null) |
727 |
return ""; // //$NON-NLS-1$ |
728 |
return node.getNodeValue(); |
729 |
} |
730 |
|
731 |
private static Node removeNode(String nodeName, NamedNodeMap nodeMap) { |
732 |
try { |
733 |
return nodeMap.removeNamedItem(nodeName); |
734 |
} catch (DOMException e) { |
735 |
if (e.code != DOMException.NOT_FOUND_ERR) |
736 |
throw e; |
737 |
return null; |
738 |
} |
739 |
} |
629 |
|
740 |
|
630 |
/** |
741 |
/** |
631 |
* Encode some patterns into XML parameter tag |
742 |
* Encode some patterns into XML parameter tag |