Source Code Cross Referenced for ClasspathEntry.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » core » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.internal.core;
0011:
0012:        import java.io.ByteArrayOutputStream;
0013:        import java.io.File;
0014:        import java.io.OutputStreamWriter;
0015:        import java.io.UnsupportedEncodingException;
0016:        import java.util.ArrayList;
0017:        import java.util.HashMap;
0018:        import java.util.HashSet;
0019:        import java.util.Map;
0020:
0021:        import org.eclipse.core.resources.IProject;
0022:        import org.eclipse.core.resources.IResource;
0023:        import org.eclipse.core.resources.IWorkspaceRoot;
0024:        import org.eclipse.core.resources.ResourcesPlugin;
0025:        import org.eclipse.core.runtime.AssertionFailedException;
0026:        import org.eclipse.core.runtime.CoreException;
0027:        import org.eclipse.core.runtime.IPath;
0028:        import org.eclipse.core.runtime.IStatus;
0029:        import org.eclipse.core.runtime.Path;
0030:        import org.eclipse.jdt.core.IAccessRule;
0031:        import org.eclipse.jdt.core.IClasspathAttribute;
0032:        import org.eclipse.jdt.core.IClasspathContainer;
0033:        import org.eclipse.jdt.core.IClasspathEntry;
0034:        import org.eclipse.jdt.core.IJavaModelStatus;
0035:        import org.eclipse.jdt.core.IJavaModelStatusConstants;
0036:        import org.eclipse.jdt.core.IJavaProject;
0037:        import org.eclipse.jdt.core.IPackageFragmentRoot;
0038:        import org.eclipse.jdt.core.JavaCore;
0039:        import org.eclipse.jdt.core.JavaModelException;
0040:        import org.eclipse.jdt.core.compiler.CharOperation;
0041:        import org.eclipse.jdt.core.compiler.IProblem;
0042:        import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
0043:        import org.eclipse.jdt.internal.compiler.env.AccessRule;
0044:        import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
0045:        import org.eclipse.jdt.internal.core.util.Messages;
0046:        import org.eclipse.jdt.internal.core.util.Util;
0047:        import org.w3c.dom.DOMException;
0048:        import org.w3c.dom.Element;
0049:        import org.w3c.dom.NamedNodeMap;
0050:        import org.w3c.dom.Node;
0051:        import org.w3c.dom.NodeList;
0052:        import org.w3c.dom.Text;
0053:
0054:        /**
0055:         * @see IClasspathEntry
0056:         */
0057:        public class ClasspathEntry implements  IClasspathEntry {
0058:
0059:            public static final String TAG_CLASSPATH = "classpath"; //$NON-NLS-1$
0060:            public static final String TAG_CLASSPATHENTRY = "classpathentry"; //$NON-NLS-1$
0061:            public static final String TAG_OUTPUT = "output"; //$NON-NLS-1$
0062:            public static final String TAG_KIND = "kind"; //$NON-NLS-1$
0063:            public static final String TAG_PATH = "path"; //$NON-NLS-1$
0064:            public static final String TAG_SOURCEPATH = "sourcepath"; //$NON-NLS-1$
0065:            public static final String TAG_ROOTPATH = "rootpath"; //$NON-NLS-1$
0066:            public static final String TAG_EXPORTED = "exported"; //$NON-NLS-1$
0067:            public static final String TAG_INCLUDING = "including"; //$NON-NLS-1$
0068:            public static final String TAG_EXCLUDING = "excluding"; //$NON-NLS-1$
0069:            public static final String TAG_ATTRIBUTES = "attributes"; //$NON-NLS-1$
0070:            public static final String TAG_ATTRIBUTE = "attribute"; //$NON-NLS-1$
0071:            public static final String TAG_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
0072:            public static final String TAG_ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
0073:            public static final String TAG_COMBINE_ACCESS_RULES = "combineaccessrules"; //$NON-NLS-1$
0074:            public static final String TAG_ACCESS_RULES = "accessrules"; //$NON-NLS-1$
0075:            public static final String TAG_ACCESS_RULE = "accessrule"; //$NON-NLS-1$
0076:            public static final String TAG_PATTERN = "pattern"; //$NON-NLS-1$
0077:            public static final String TAG_ACCESSIBLE = "accessible"; //$NON-NLS-1$
0078:            public static final String TAG_NON_ACCESSIBLE = "nonaccessible"; //$NON-NLS-1$
0079:            public static final String TAG_DISCOURAGED = "discouraged"; //$NON-NLS-1$
0080:            public static final String TAG_IGNORE_IF_BETTER = "ignoreifbetter"; //$NON-NLS-1$
0081:
0082:            /**
0083:             * Describes the kind of classpath entry - one of
0084:             * CPE_PROJECT, CPE_LIBRARY, CPE_SOURCE, CPE_VARIABLE or CPE_CONTAINER
0085:             */
0086:            public int entryKind;
0087:
0088:            /**
0089:             * Describes the kind of package fragment roots found on
0090:             * this classpath entry - either K_BINARY or K_SOURCE or
0091:             * K_OUTPUT.
0092:             */
0093:            public int contentKind;
0094:
0095:            /**
0096:             * The meaning of the path of a classpath entry depends on its entry kind:<ul>
0097:             *	<li>Source code in the current project (<code>CPE_SOURCE</code>) -
0098:             *      The path associated with this entry is the absolute path to the root folder. </li>
0099:             *	<li>A binary library in the current project (<code>CPE_LIBRARY</code>) - the path
0100:             *		associated with this entry is the absolute path to the JAR (or root folder), and
0101:             *		in case it refers to an external JAR, then there is no associated resource in
0102:             *		the workbench.
0103:             *	<li>A required project (<code>CPE_PROJECT</code>) - the path of the entry denotes the
0104:             *		path to the corresponding project resource.</li>
0105:             *  <li>A variable entry (<code>CPE_VARIABLE</code>) - the first segment of the path
0106:             *      is the name of a classpath variable. If this classpath variable
0107:             *		is bound to the path <it>P</it>, the path of the corresponding classpath entry
0108:             *		is computed by appending to <it>P</it> the segments of the returned
0109:             *		path without the variable.</li>
0110:             *  <li> A container entry (<code>CPE_CONTAINER</code>) - the first segment of the path is denoting
0111:             *     the unique container identifier (for which a <code>ClasspathContainerInitializer</code> could be
0112:             * 	registered), and the remaining segments are used as additional hints for resolving the container entry to
0113:             * 	an actual <code>IClasspathContainer</code>.</li>
0114:             */
0115:            public IPath path;
0116:
0117:            /**
0118:             * Patterns allowing to include/exclude portions of the resource tree denoted by this entry path.
0119:             */
0120:            private IPath[] inclusionPatterns;
0121:            private char[][] fullInclusionPatternChars;
0122:            private IPath[] exclusionPatterns;
0123:            private char[][] fullExclusionPatternChars;
0124:            private final static char[][] UNINIT_PATTERNS = new char[][] { "Non-initialized yet".toCharArray() }; //$NON-NLS-1$
0125:
0126:            private boolean combineAccessRules;
0127:
0128:            private String rootID;
0129:            private AccessRuleSet accessRuleSet;
0130:
0131:            static class UnknownXmlElements {
0132:                String[] attributes;
0133:                ArrayList children;
0134:            }
0135:
0136:            /*
0137:             * Default inclusion pattern set
0138:             */
0139:            public final static IPath[] INCLUDE_ALL = {};
0140:
0141:            /*
0142:             * Default exclusion pattern set
0143:             */
0144:            public final static IPath[] EXCLUDE_NONE = {};
0145:
0146:            /*
0147:             * Default extra attributes
0148:             */
0149:            public final static IClasspathAttribute[] NO_EXTRA_ATTRIBUTES = {};
0150:
0151:            /*
0152:             * Default access rules
0153:             */
0154:            public final static IAccessRule[] NO_ACCESS_RULES = {};
0155:
0156:            /**
0157:             * Describes the path to the source archive associated with this
0158:             * classpath entry, or <code>null</code> if this classpath entry has no
0159:             * source attachment.
0160:             * <p>
0161:             * Only library and variable classpath entries may have source attachments.
0162:             * For library classpath entries, the result path (if present) locates a source
0163:             * archive. For variable classpath entries, the result path (if present) has
0164:             * an analogous form and meaning as the variable path, namely the first segment
0165:             * is the name of a classpath variable.
0166:             */
0167:            public IPath sourceAttachmentPath;
0168:
0169:            /**
0170:             * Describes the path within the source archive where package fragments
0171:             * are located. An empty path indicates that packages are located at
0172:             * the root of the source archive. Returns a non-<code>null</code> value
0173:             * if and only if <code>getSourceAttachmentPath</code> returns
0174:             * a non-<code>null</code> value.
0175:             */
0176:            public IPath sourceAttachmentRootPath;
0177:
0178:            /**
0179:             * Specific output location (for this source entry)
0180:             */
0181:            public IPath specificOutputLocation;
0182:
0183:            /**
0184:             * A constant indicating an output location.
0185:             */
0186:            public static final int K_OUTPUT = 10;
0187:
0188:            /**
0189:             * The export flag
0190:             */
0191:            public boolean isExported;
0192:
0193:            /*
0194:             * The extra attributes
0195:             */
0196:            IClasspathAttribute[] extraAttributes;
0197:
0198:            /**
0199:             * Creates a class path entry of the specified kind with the given path.
0200:             */
0201:            public ClasspathEntry(int contentKind, int entryKind, IPath path,
0202:                    IPath[] inclusionPatterns, IPath[] exclusionPatterns,
0203:                    IPath sourceAttachmentPath, IPath sourceAttachmentRootPath,
0204:                    IPath specificOutputLocation, boolean isExported,
0205:                    IAccessRule[] accessRules, boolean combineAccessRules,
0206:                    IClasspathAttribute[] extraAttributes) {
0207:
0208:                this .contentKind = contentKind;
0209:                this .entryKind = entryKind;
0210:                this .path = path;
0211:                this .inclusionPatterns = inclusionPatterns;
0212:                this .exclusionPatterns = exclusionPatterns;
0213:
0214:                int length;
0215:                if (accessRules != null && (length = accessRules.length) > 0) {
0216:                    AccessRule[] rules = new AccessRule[length];
0217:                    System.arraycopy(accessRules, 0, rules, 0, length);
0218:                    this .accessRuleSet = new AccessRuleSet(rules,
0219:                            getMessageTemplates());
0220:                }
0221:                //		else { -- implicit!
0222:                //			this.accessRuleSet = null;
0223:                //		}
0224:
0225:                this .combineAccessRules = combineAccessRules;
0226:                this .extraAttributes = extraAttributes;
0227:
0228:                if (inclusionPatterns != INCLUDE_ALL
0229:                        && inclusionPatterns.length > 0) {
0230:                    this .fullInclusionPatternChars = UNINIT_PATTERNS;
0231:                }
0232:                if (exclusionPatterns.length > 0) {
0233:                    this .fullExclusionPatternChars = UNINIT_PATTERNS;
0234:                }
0235:                this .sourceAttachmentPath = sourceAttachmentPath;
0236:                this .sourceAttachmentRootPath = sourceAttachmentRootPath;
0237:                this .specificOutputLocation = specificOutputLocation;
0238:                this .isExported = isExported;
0239:            }
0240:
0241:            public boolean combineAccessRules() {
0242:                return this .combineAccessRules;
0243:            }
0244:
0245:            /**
0246:             * Used to perform export/restriction propagation across referring projects/containers
0247:             */
0248:            public ClasspathEntry combineWith(ClasspathEntry referringEntry) {
0249:                if (referringEntry == null)
0250:                    return this ;
0251:                if (referringEntry.isExported()
0252:                        || referringEntry.getAccessRuleSet() != null) {
0253:                    boolean combine = this .entryKind == CPE_SOURCE
0254:                            || referringEntry.combineAccessRules();
0255:                    return new ClasspathEntry(getContentKind(), getEntryKind(),
0256:                            getPath(), this .inclusionPatterns,
0257:                            this .exclusionPatterns, getSourceAttachmentPath(),
0258:                            getSourceAttachmentRootPath(),
0259:                            getOutputLocation(),
0260:                            referringEntry.isExported() || this .isExported, // duplicate container entry for tagging it as exported
0261:                            combine(referringEntry.getAccessRules(),
0262:                                    getAccessRules(), combine),
0263:                            this .combineAccessRules, this .extraAttributes);
0264:                }
0265:                // no need to clone
0266:                return this ;
0267:            }
0268:
0269:            private IAccessRule[] combine(IAccessRule[] referringRules,
0270:                    IAccessRule[] rules, boolean combine) {
0271:                if (!combine)
0272:                    return rules;
0273:                if (rules == null || rules.length == 0)
0274:                    return referringRules;
0275:
0276:                // concat access rules
0277:                int referringRulesLength = referringRules.length;
0278:                int accessRulesLength = rules.length;
0279:                int rulesLength = referringRulesLength + accessRulesLength;
0280:                IAccessRule[] result = new IAccessRule[rulesLength];
0281:                System.arraycopy(referringRules, 0, result, 0,
0282:                        referringRulesLength);
0283:                System.arraycopy(rules, 0, result, referringRulesLength,
0284:                        accessRulesLength);
0285:
0286:                return result;
0287:            }
0288:
0289:            static IClasspathAttribute[] decodeExtraAttributes(
0290:                    NodeList attributes) {
0291:                if (attributes == null)
0292:                    return NO_EXTRA_ATTRIBUTES;
0293:                int length = attributes.getLength();
0294:                if (length == 0)
0295:                    return NO_EXTRA_ATTRIBUTES;
0296:                IClasspathAttribute[] result = new IClasspathAttribute[length];
0297:                int index = 0;
0298:                for (int i = 0; i < length; ++i) {
0299:                    Node node = attributes.item(i);
0300:                    if (node.getNodeType() == Node.ELEMENT_NODE) {
0301:                        Element attribute = (Element) node;
0302:                        String name = attribute
0303:                                .getAttribute(TAG_ATTRIBUTE_NAME);
0304:                        if (name == null)
0305:                            continue;
0306:                        String value = attribute
0307:                                .getAttribute(TAG_ATTRIBUTE_VALUE);
0308:                        if (value == null)
0309:                            continue;
0310:                        result[index++] = new ClasspathAttribute(name, value);
0311:                    }
0312:                }
0313:                if (index != length)
0314:                    System.arraycopy(result, 0,
0315:                            result = new IClasspathAttribute[index], 0, index);
0316:                return result;
0317:            }
0318:
0319:            static IAccessRule[] decodeAccessRules(NodeList list) {
0320:                if (list == null)
0321:                    return null;
0322:                int length = list.getLength();
0323:                if (length == 0)
0324:                    return null;
0325:                IAccessRule[] result = new IAccessRule[length];
0326:                int index = 0;
0327:                for (int i = 0; i < length; i++) {
0328:                    Node accessRule = list.item(i);
0329:                    if (accessRule.getNodeType() == Node.ELEMENT_NODE) {
0330:                        Element elementAccessRule = (Element) accessRule;
0331:                        String pattern = elementAccessRule
0332:                                .getAttribute(TAG_PATTERN);
0333:                        if (pattern == null)
0334:                            continue;
0335:                        String tagKind = elementAccessRule
0336:                                .getAttribute(TAG_KIND);
0337:                        int kind;
0338:                        if (TAG_ACCESSIBLE.equals(tagKind))
0339:                            kind = IAccessRule.K_ACCESSIBLE;
0340:                        else if (TAG_NON_ACCESSIBLE.equals(tagKind))
0341:                            kind = IAccessRule.K_NON_ACCESSIBLE;
0342:                        else if (TAG_DISCOURAGED.equals(tagKind))
0343:                            kind = IAccessRule.K_DISCOURAGED;
0344:                        else
0345:                            continue;
0346:                        boolean ignoreIfBetter = "true".equals(elementAccessRule.getAttribute(TAG_IGNORE_IF_BETTER)); //$NON-NLS-1$
0347:                        result[index++] = new ClasspathAccessRule(new Path(
0348:                                pattern), ignoreIfBetter ? kind
0349:                                | IAccessRule.IGNORE_IF_BETTER : kind);
0350:                    }
0351:                }
0352:                if (index != length)
0353:                    System.arraycopy(result, 0,
0354:                            result = new IAccessRule[index], 0, index);
0355:                return result;
0356:            }
0357:
0358:            /**
0359:             * Decode some element tag containing a sequence of patterns into IPath[]
0360:             */
0361:            private static IPath[] decodePatterns(NamedNodeMap nodeMap,
0362:                    String tag) {
0363:                String sequence = removeAttribute(tag, nodeMap);
0364:                if (!sequence.equals("")) { //$NON-NLS-1$
0365:                    char[][] patterns = CharOperation.splitOn('|', sequence
0366:                            .toCharArray());
0367:                    int patternCount;
0368:                    if ((patternCount = patterns.length) > 0) {
0369:                        IPath[] paths = new IPath[patternCount];
0370:                        int index = 0;
0371:                        for (int j = 0; j < patternCount; j++) {
0372:                            char[] pattern = patterns[j];
0373:                            if (pattern.length == 0)
0374:                                continue; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=105581
0375:                            paths[index++] = new Path(new String(pattern));
0376:                        }
0377:                        if (index < patternCount)
0378:                            System.arraycopy(paths, 0,
0379:                                    paths = new IPath[index], 0, index);
0380:                        return paths;
0381:                    }
0382:                }
0383:                return null;
0384:            }
0385:
0386:            private static void decodeUnknownNode(Node node,
0387:                    StringBuffer buffer, IJavaProject project) {
0388:                ByteArrayOutputStream s = new ByteArrayOutputStream();
0389:                OutputStreamWriter writer;
0390:                try {
0391:                    writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
0392:                    XMLWriter xmlWriter = new XMLWriter(writer, project, false/*don't print XML version*/);
0393:                    decodeUnknownNode(node, xmlWriter, true/*insert new line*/);
0394:                    xmlWriter.flush();
0395:                    xmlWriter.close();
0396:                    buffer.append(s.toString("UTF8")); //$NON-NLS-1$
0397:                } catch (UnsupportedEncodingException e) {
0398:                    // ignore (UTF8 is always supported)
0399:                }
0400:            }
0401:
0402:            private static void decodeUnknownNode(Node node,
0403:                    XMLWriter xmlWriter, boolean insertNewLine) {
0404:                switch (node.getNodeType()) {
0405:                case Node.ELEMENT_NODE:
0406:                    NamedNodeMap attributes;
0407:                    HashMap parameters = null;
0408:                    if ((attributes = node.getAttributes()) != null) {
0409:                        int length = attributes.getLength();
0410:                        if (length > 0) {
0411:                            parameters = new HashMap();
0412:                            for (int i = 0; i < length; i++) {
0413:                                Node attribute = attributes.item(i);
0414:                                parameters.put(attribute.getNodeName(),
0415:                                        attribute.getNodeValue());
0416:                            }
0417:                        }
0418:                    }
0419:                    NodeList children = node.getChildNodes();
0420:                    int childrenLength = children.getLength();
0421:                    String nodeName = node.getNodeName();
0422:                    xmlWriter.printTag(nodeName, parameters,
0423:                            false/*don't insert tab*/,
0424:                            false/*don't insert new line*/,
0425:                            childrenLength == 0/*close tag if no children*/);
0426:                    if (childrenLength > 0) {
0427:                        for (int i = 0; i < childrenLength; i++) {
0428:                            decodeUnknownNode(children.item(i), xmlWriter,
0429:                                    false/*don't insert new line*/);
0430:                        }
0431:                        xmlWriter.endTag(nodeName, false/*don't insert tab*/,
0432:                                insertNewLine);
0433:                    }
0434:                    break;
0435:                case Node.TEXT_NODE:
0436:                    String data = ((Text) node).getData();
0437:                    xmlWriter.printString(data, false/*don't insert tab*/,
0438:                            false/*don't insert new line*/);
0439:                    break;
0440:                }
0441:            }
0442:
0443:            /*
0444:             * Returns a char based representation of the exclusions patterns full path.
0445:             */
0446:            public char[][] fullExclusionPatternChars() {
0447:
0448:                if (this .fullExclusionPatternChars == UNINIT_PATTERNS) {
0449:                    int length = this .exclusionPatterns.length;
0450:                    this .fullExclusionPatternChars = new char[length][];
0451:                    IPath prefixPath = this .path.removeTrailingSeparator();
0452:                    for (int i = 0; i < length; i++) {
0453:                        this .fullExclusionPatternChars[i] = prefixPath.append(
0454:                                this .exclusionPatterns[i]).toString()
0455:                                .toCharArray();
0456:                    }
0457:                }
0458:                return this .fullExclusionPatternChars;
0459:            }
0460:
0461:            /*
0462:             * Returns a char based representation of the exclusions patterns full path.
0463:             */
0464:            public char[][] fullInclusionPatternChars() {
0465:
0466:                if (this .fullInclusionPatternChars == UNINIT_PATTERNS) {
0467:                    int length = this .inclusionPatterns.length;
0468:                    this .fullInclusionPatternChars = new char[length][];
0469:                    IPath prefixPath = this .path.removeTrailingSeparator();
0470:                    for (int i = 0; i < length; i++) {
0471:                        this .fullInclusionPatternChars[i] = prefixPath.append(
0472:                                this .inclusionPatterns[i]).toString()
0473:                                .toCharArray();
0474:                    }
0475:                }
0476:                return this .fullInclusionPatternChars;
0477:            }
0478:
0479:            /**
0480:             * Returns the XML encoding of the class path.
0481:             */
0482:            public void elementEncode(XMLWriter writer, IPath projectPath,
0483:                    boolean indent, boolean newLine, Map unknownElements) {
0484:                HashMap parameters = new HashMap();
0485:
0486:                parameters.put(TAG_KIND, ClasspathEntry
0487:                        .kindToString(this .entryKind));
0488:
0489:                IPath xmlPath = this .path;
0490:                if (this .entryKind != IClasspathEntry.CPE_VARIABLE
0491:                        && this .entryKind != IClasspathEntry.CPE_CONTAINER) {
0492:                    // translate to project relative from absolute (unless a device path)
0493:                    if (xmlPath.isAbsolute()) {
0494:                        if (projectPath != null
0495:                                && projectPath.isPrefixOf(xmlPath)) {
0496:                            if (xmlPath.segment(0).equals(
0497:                                    projectPath.segment(0))) {
0498:                                xmlPath = xmlPath.removeFirstSegments(1);
0499:                                xmlPath = xmlPath.makeRelative();
0500:                            } else {
0501:                                xmlPath = xmlPath.makeAbsolute();
0502:                            }
0503:                        }
0504:                    }
0505:                }
0506:                parameters.put(TAG_PATH, String.valueOf(xmlPath));
0507:
0508:                if (this .sourceAttachmentPath != null) {
0509:                    xmlPath = this .sourceAttachmentPath;
0510:                    // translate to project relative from absolute
0511:                    if (this .entryKind != IClasspathEntry.CPE_VARIABLE
0512:                            && projectPath != null
0513:                            && projectPath.isPrefixOf(xmlPath)) {
0514:                        if (xmlPath.segment(0).equals(projectPath.segment(0))) {
0515:                            xmlPath = xmlPath.removeFirstSegments(1);
0516:                            xmlPath = xmlPath.makeRelative();
0517:                        }
0518:                    }
0519:                    parameters.put(TAG_SOURCEPATH, String.valueOf(xmlPath));
0520:                }
0521:                if (this .sourceAttachmentRootPath != null) {
0522:                    parameters.put(TAG_ROOTPATH, String
0523:                            .valueOf(this .sourceAttachmentRootPath));
0524:                }
0525:                if (this .isExported) {
0526:                    parameters.put(TAG_EXPORTED, "true");//$NON-NLS-1$
0527:                }
0528:                encodePatterns(this .inclusionPatterns, TAG_INCLUDING,
0529:                        parameters);
0530:                encodePatterns(this .exclusionPatterns, TAG_EXCLUDING,
0531:                        parameters);
0532:                if (this .entryKind == CPE_PROJECT && !this .combineAccessRules)
0533:                    parameters.put(TAG_COMBINE_ACCESS_RULES, "false"); //$NON-NLS-1$
0534:
0535:                // unknown attributes
0536:                UnknownXmlElements unknownXmlElements = unknownElements == null ? null
0537:                        : (UnknownXmlElements) unknownElements.get(this .path);
0538:                String[] unknownAttributes;
0539:                if (unknownXmlElements != null
0540:                        && (unknownAttributes = unknownXmlElements.attributes) != null)
0541:                    for (int i = 0, length = unknownAttributes.length; i < length; i += 2) {
0542:                        String tagName = unknownAttributes[i];
0543:                        String tagValue = unknownAttributes[i + 1];
0544:                        parameters.put(tagName, tagValue);
0545:                    }
0546:
0547:                if (this .specificOutputLocation != null) {
0548:                    IPath outputLocation = this .specificOutputLocation
0549:                            .removeFirstSegments(1);
0550:                    outputLocation = outputLocation.makeRelative();
0551:                    parameters.put(TAG_OUTPUT, String.valueOf(outputLocation));
0552:                }
0553:
0554:                boolean hasExtraAttributes = this .extraAttributes.length != 0;
0555:                boolean hasRestrictions = getAccessRuleSet() != null; // access rule set is null if no access rules
0556:                ArrayList unknownChildren = unknownXmlElements != null ? unknownXmlElements.children
0557:                        : null;
0558:                boolean hasUnknownChildren = unknownChildren != null;
0559:                writer
0560:                        .printTag(TAG_CLASSPATHENTRY, parameters, indent,
0561:                                newLine, !hasExtraAttributes
0562:                                        && !hasRestrictions
0563:                                        && !hasUnknownChildren/*close tag if no extra attributes, no restriction and no unknown children*/);
0564:
0565:                if (hasExtraAttributes)
0566:                    encodeExtraAttributes(writer, indent, newLine);
0567:
0568:                if (hasRestrictions)
0569:                    encodeAccessRules(writer, indent, newLine);
0570:
0571:                if (hasUnknownChildren)
0572:                    encodeUnknownChildren(writer, indent, newLine,
0573:                            unknownChildren);
0574:
0575:                if (hasExtraAttributes || hasRestrictions || hasUnknownChildren)
0576:                    writer
0577:                            .endTag(TAG_CLASSPATHENTRY, indent, true/*insert new line*/);
0578:            }
0579:
0580:            void encodeExtraAttributes(XMLWriter writer, boolean indent,
0581:                    boolean newLine) {
0582:                writer.startTag(TAG_ATTRIBUTES, indent);
0583:                for (int i = 0; i < this .extraAttributes.length; i++) {
0584:                    IClasspathAttribute attribute = this .extraAttributes[i];
0585:                    HashMap parameters = new HashMap();
0586:                    parameters.put(TAG_ATTRIBUTE_NAME, attribute.getName());
0587:                    parameters.put(TAG_ATTRIBUTE_VALUE, attribute.getValue());
0588:                    writer.printTag(TAG_ATTRIBUTE, parameters, indent, newLine,
0589:                            true);
0590:                }
0591:                writer.endTag(TAG_ATTRIBUTES, indent, true/*insert new line*/);
0592:            }
0593:
0594:            void encodeAccessRules(XMLWriter writer, boolean indent,
0595:                    boolean newLine) {
0596:
0597:                writer.startTag(TAG_ACCESS_RULES, indent);
0598:                AccessRule[] rules = getAccessRuleSet().getAccessRules();
0599:                for (int i = 0, length = rules.length; i < length; i++) {
0600:                    encodeAccessRule(rules[i], writer, indent, newLine);
0601:                }
0602:                writer
0603:                        .endTag(TAG_ACCESS_RULES, indent, true/*insert new line*/);
0604:            }
0605:
0606:            private void encodeAccessRule(AccessRule accessRule,
0607:                    XMLWriter writer, boolean indent, boolean newLine) {
0608:
0609:                HashMap parameters = new HashMap();
0610:                parameters.put(TAG_PATTERN, new String(accessRule.pattern));
0611:
0612:                switch (accessRule.getProblemId()) {
0613:                case IProblem.ForbiddenReference:
0614:                    parameters.put(TAG_KIND, TAG_NON_ACCESSIBLE);
0615:                    break;
0616:                case IProblem.DiscouragedReference:
0617:                    parameters.put(TAG_KIND, TAG_DISCOURAGED);
0618:                    break;
0619:                default:
0620:                    parameters.put(TAG_KIND, TAG_ACCESSIBLE);
0621:                    break;
0622:                }
0623:                if (accessRule.ignoreIfBetter())
0624:                    parameters.put(TAG_IGNORE_IF_BETTER, "true"); //$NON-NLS-1$
0625:
0626:                writer.printTag(TAG_ACCESS_RULE, parameters, indent, newLine,
0627:                        true);
0628:
0629:            }
0630:
0631:            private void encodeUnknownChildren(XMLWriter writer,
0632:                    boolean indent, boolean newLine, ArrayList unknownChildren) {
0633:                for (int i = 0, length = unknownChildren.size(); i < length; i++) {
0634:                    String child = (String) unknownChildren.get(i);
0635:                    writer
0636:                            .printString(child, indent, false/*don't insert new line*/);
0637:                }
0638:            }
0639:
0640:            public static IClasspathEntry elementDecode(Element element,
0641:                    IJavaProject project, Map unknownElements) {
0642:
0643:                IPath projectPath = project.getProject().getFullPath();
0644:                NamedNodeMap attributes = element.getAttributes();
0645:                NodeList children = element.getChildNodes();
0646:                boolean[] foundChildren = new boolean[children.getLength()];
0647:                String kindAttr = removeAttribute(TAG_KIND, attributes);
0648:                String pathAttr = removeAttribute(TAG_PATH, attributes);
0649:
0650:                // ensure path is absolute
0651:                IPath path = new Path(pathAttr);
0652:                int kind = kindFromString(kindAttr);
0653:                if (kind != IClasspathEntry.CPE_VARIABLE
0654:                        && kind != IClasspathEntry.CPE_CONTAINER
0655:                        && !path.isAbsolute()) {
0656:                    path = projectPath.append(path);
0657:                }
0658:                // source attachment info (optional)
0659:                IPath sourceAttachmentPath = element
0660:                        .hasAttribute(TAG_SOURCEPATH) ? new Path(
0661:                        removeAttribute(TAG_SOURCEPATH, attributes)) : null;
0662:                if (kind != IClasspathEntry.CPE_VARIABLE
0663:                        && sourceAttachmentPath != null
0664:                        && !sourceAttachmentPath.isAbsolute()) {
0665:                    sourceAttachmentPath = projectPath
0666:                            .append(sourceAttachmentPath);
0667:                }
0668:                IPath sourceAttachmentRootPath = element
0669:                        .hasAttribute(TAG_ROOTPATH) ? new Path(removeAttribute(
0670:                        TAG_ROOTPATH, attributes)) : null;
0671:
0672:                // exported flag (optional)
0673:                boolean isExported = removeAttribute(TAG_EXPORTED, attributes)
0674:                        .equals("true"); //$NON-NLS-1$
0675:
0676:                // inclusion patterns (optional)
0677:                IPath[] inclusionPatterns = decodePatterns(attributes,
0678:                        TAG_INCLUDING);
0679:                if (inclusionPatterns == null)
0680:                    inclusionPatterns = INCLUDE_ALL;
0681:
0682:                // exclusion patterns (optional)
0683:                IPath[] exclusionPatterns = decodePatterns(attributes,
0684:                        TAG_EXCLUDING);
0685:                if (exclusionPatterns == null)
0686:                    exclusionPatterns = EXCLUDE_NONE;
0687:
0688:                // access rules (optional)
0689:                NodeList attributeList = getChildAttributes(TAG_ACCESS_RULES,
0690:                        children, foundChildren);
0691:                IAccessRule[] accessRules = decodeAccessRules(attributeList);
0692:
0693:                // backward compatibility
0694:                if (accessRules == null) {
0695:                    accessRules = getAccessRules(inclusionPatterns,
0696:                            exclusionPatterns);
0697:                }
0698:
0699:                // combine access rules (optional)
0700:                boolean combineAccessRestrictions = !removeAttribute(
0701:                        TAG_COMBINE_ACCESS_RULES, attributes).equals("false"); //$NON-NLS-1$
0702:
0703:                // extra attributes (optional)
0704:                attributeList = getChildAttributes(TAG_ATTRIBUTES, children,
0705:                        foundChildren);
0706:                IClasspathAttribute[] extraAttributes = decodeExtraAttributes(attributeList);
0707:
0708:                // custom output location
0709:                IPath outputLocation = element.hasAttribute(TAG_OUTPUT) ? projectPath
0710:                        .append(removeAttribute(TAG_OUTPUT, attributes))
0711:                        : null;
0712:
0713:                String[] unknownAttributes = null;
0714:                ArrayList unknownChildren = null;
0715:
0716:                if (unknownElements != null) {
0717:                    // unknown attributes
0718:                    int unknownAttributeLength = attributes.getLength();
0719:                    if (unknownAttributeLength != 0) {
0720:                        unknownAttributes = new String[unknownAttributeLength * 2];
0721:                        for (int i = 0; i < unknownAttributeLength; i++) {
0722:                            Node attribute = attributes.item(i);
0723:                            unknownAttributes[i * 2] = attribute.getNodeName();
0724:                            unknownAttributes[i * 2 + 1] = attribute
0725:                                    .getNodeValue();
0726:                        }
0727:                    }
0728:
0729:                    // unknown children
0730:                    for (int i = 0, length = foundChildren.length; i < length; i++) {
0731:                        if (!foundChildren[i]) {
0732:                            Node node = children.item(i);
0733:                            if (node.getNodeType() != Node.ELEMENT_NODE)
0734:                                continue;
0735:                            if (unknownChildren == null)
0736:                                unknownChildren = new ArrayList();
0737:                            StringBuffer buffer = new StringBuffer();
0738:                            decodeUnknownNode(node, buffer, project);
0739:                            unknownChildren.add(buffer.toString());
0740:                        }
0741:                    }
0742:                }
0743:
0744:                // recreate the CP entry
0745:                IClasspathEntry entry = null;
0746:                switch (kind) {
0747:
0748:                case IClasspathEntry.CPE_PROJECT:
0749:                    entry = new ClasspathEntry(IPackageFragmentRoot.K_SOURCE,
0750:                            IClasspathEntry.CPE_PROJECT,
0751:                            path,
0752:                            ClasspathEntry.INCLUDE_ALL, // inclusion patterns
0753:                            ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
0754:                            null, // source attachment
0755:                            null, // source attachment root
0756:                            null, // specific output folder
0757:                            isExported, accessRules, combineAccessRestrictions,
0758:                            extraAttributes);
0759:                    break;
0760:                case IClasspathEntry.CPE_LIBRARY:
0761:                    entry = JavaCore.newLibraryEntry(path,
0762:                            sourceAttachmentPath, sourceAttachmentRootPath,
0763:                            accessRules, extraAttributes, isExported);
0764:                    break;
0765:                case IClasspathEntry.CPE_SOURCE:
0766:                    // must be an entry in this project or specify another project
0767:                    String projSegment = path.segment(0);
0768:                    if (projSegment != null
0769:                            && projSegment.equals(project.getElementName())) { // this project
0770:                        entry = JavaCore.newSourceEntry(path,
0771:                                inclusionPatterns, exclusionPatterns,
0772:                                outputLocation, extraAttributes);
0773:                    } else {
0774:                        if (path.segmentCount() == 1) {
0775:                            // another project
0776:                            entry = JavaCore.newProjectEntry(path, accessRules,
0777:                                    combineAccessRestrictions, extraAttributes,
0778:                                    isExported);
0779:                        } else {
0780:                            // an invalid source folder
0781:                            entry = JavaCore.newSourceEntry(path,
0782:                                    inclusionPatterns, exclusionPatterns,
0783:                                    outputLocation, extraAttributes);
0784:                        }
0785:                    }
0786:                    break;
0787:                case IClasspathEntry.CPE_VARIABLE:
0788:                    entry = JavaCore.newVariableEntry(path,
0789:                            sourceAttachmentPath, sourceAttachmentRootPath,
0790:                            accessRules, extraAttributes, isExported);
0791:                    break;
0792:                case IClasspathEntry.CPE_CONTAINER:
0793:                    entry = JavaCore.newContainerEntry(path, accessRules,
0794:                            extraAttributes, isExported);
0795:                    break;
0796:                case ClasspathEntry.K_OUTPUT:
0797:                    if (!path.isAbsolute())
0798:                        return null;
0799:                    entry = new ClasspathEntry(ClasspathEntry.K_OUTPUT,
0800:                            IClasspathEntry.CPE_LIBRARY, path, INCLUDE_ALL,
0801:                            EXCLUDE_NONE, null, // source attachment
0802:                            null, // source attachment root
0803:                            null, // custom output location
0804:                            false, null, // no access rules
0805:                            false, // no accessible files to combine
0806:                            NO_EXTRA_ATTRIBUTES);
0807:                    break;
0808:                default:
0809:                    throw new AssertionFailedException(Messages.bind(
0810:                            Messages.classpath_unknownKind, kindAttr));
0811:                }
0812:
0813:                if (unknownAttributes != null || unknownChildren != null) {
0814:                    UnknownXmlElements unknownXmlElements = new UnknownXmlElements();
0815:                    unknownXmlElements.attributes = unknownAttributes;
0816:                    unknownXmlElements.children = unknownChildren;
0817:                    unknownElements.put(path, unknownXmlElements);
0818:                }
0819:
0820:                return entry;
0821:            }
0822:
0823:            public static NodeList getChildAttributes(String childName,
0824:                    NodeList children, boolean[] foundChildren) {
0825:                for (int i = 0, length = foundChildren.length; i < length; i++) {
0826:                    Node node = children.item(i);
0827:                    if (childName.equals(node.getNodeName())) {
0828:                        foundChildren[i] = true;
0829:                        return node.getChildNodes();
0830:                    }
0831:                }
0832:                return null;
0833:            }
0834:
0835:            private static String removeAttribute(String nodeName,
0836:                    NamedNodeMap nodeMap) {
0837:                Node node = removeNode(nodeName, nodeMap);
0838:                if (node == null)
0839:                    return ""; // //$NON-NLS-1$
0840:                return node.getNodeValue();
0841:            }
0842:
0843:            private static Node removeNode(String nodeName, NamedNodeMap nodeMap) {
0844:                try {
0845:                    return nodeMap.removeNamedItem(nodeName);
0846:                } catch (DOMException e) {
0847:                    if (e.code != DOMException.NOT_FOUND_ERR)
0848:                        throw e;
0849:                    return null;
0850:                }
0851:            }
0852:
0853:            /**
0854:             * Encode some patterns into XML parameter tag
0855:             */
0856:            private static void encodePatterns(IPath[] patterns, String tag,
0857:                    Map parameters) {
0858:                if (patterns != null && patterns.length > 0) {
0859:                    StringBuffer rule = new StringBuffer(10);
0860:                    for (int i = 0, max = patterns.length; i < max; i++) {
0861:                        if (i > 0)
0862:                            rule.append('|');
0863:                        rule.append(patterns[i]);
0864:                    }
0865:                    parameters.put(tag, String.valueOf(rule));
0866:                }
0867:            }
0868:
0869:            /**
0870:             * Returns true if the given object is a classpath entry
0871:             * with equivalent attributes.
0872:             */
0873:            public boolean equals(Object object) {
0874:                if (this  == object)
0875:                    return true;
0876:                if (object instanceof  ClasspathEntry) {
0877:                    ClasspathEntry otherEntry = (ClasspathEntry) object;
0878:
0879:                    if (this .contentKind != otherEntry.getContentKind())
0880:                        return false;
0881:
0882:                    if (this .entryKind != otherEntry.getEntryKind())
0883:                        return false;
0884:
0885:                    if (this .isExported != otherEntry.isExported())
0886:                        return false;
0887:
0888:                    if (!this .path.equals(otherEntry.getPath()))
0889:                        return false;
0890:
0891:                    IPath otherPath = otherEntry.getSourceAttachmentPath();
0892:                    if (this .sourceAttachmentPath == null) {
0893:                        if (otherPath != null)
0894:                            return false;
0895:                    } else {
0896:                        if (!this .sourceAttachmentPath.equals(otherPath))
0897:                            return false;
0898:                    }
0899:
0900:                    otherPath = otherEntry.getSourceAttachmentRootPath();
0901:                    if (this .sourceAttachmentRootPath == null) {
0902:                        if (otherPath != null)
0903:                            return false;
0904:                    } else {
0905:                        if (!this .sourceAttachmentRootPath.equals(otherPath))
0906:                            return false;
0907:                    }
0908:
0909:                    if (!equalPatterns(this .inclusionPatterns, otherEntry
0910:                            .getInclusionPatterns()))
0911:                        return false;
0912:                    if (!equalPatterns(this .exclusionPatterns, otherEntry
0913:                            .getExclusionPatterns()))
0914:                        return false;
0915:                    AccessRuleSet otherRuleSet = otherEntry.getAccessRuleSet();
0916:                    if (getAccessRuleSet() != null) {
0917:                        if (!getAccessRuleSet().equals(otherRuleSet))
0918:                            return false;
0919:                    } else if (otherRuleSet != null)
0920:                        return false;
0921:                    if (this .combineAccessRules != otherEntry
0922:                            .combineAccessRules())
0923:                        return false;
0924:                    otherPath = otherEntry.getOutputLocation();
0925:                    if (this .specificOutputLocation == null) {
0926:                        if (otherPath != null)
0927:                            return false;
0928:                    } else {
0929:                        if (!this .specificOutputLocation.equals(otherPath))
0930:                            return false;
0931:                    }
0932:                    if (!equalAttributes(this .extraAttributes, otherEntry
0933:                            .getExtraAttributes()))
0934:                        return false;
0935:                    return true;
0936:                } else {
0937:                    return false;
0938:                }
0939:            }
0940:
0941:            private static boolean equalAttributes(
0942:                    IClasspathAttribute[] firstAttributes,
0943:                    IClasspathAttribute[] secondAttributes) {
0944:                if (firstAttributes != secondAttributes) {
0945:                    if (firstAttributes == null)
0946:                        return false;
0947:                    int length = firstAttributes.length;
0948:                    if (secondAttributes == null
0949:                            || secondAttributes.length != length)
0950:                        return false;
0951:                    for (int i = 0; i < length; i++) {
0952:                        if (!firstAttributes[i].equals(secondAttributes[i]))
0953:                            return false;
0954:                    }
0955:                }
0956:                return true;
0957:            }
0958:
0959:            private static boolean equalPatterns(IPath[] firstPatterns,
0960:                    IPath[] secondPatterns) {
0961:                if (firstPatterns != secondPatterns) {
0962:                    if (firstPatterns == null)
0963:                        return false;
0964:                    int length = firstPatterns.length;
0965:                    if (secondPatterns == null
0966:                            || secondPatterns.length != length)
0967:                        return false;
0968:                    for (int i = 0; i < length; i++) {
0969:                        // compare toStrings instead of IPaths
0970:                        // since IPath.equals is specified to ignore trailing separators
0971:                        if (!firstPatterns[i].toString().equals(
0972:                                secondPatterns[i].toString()))
0973:                            return false;
0974:                    }
0975:                }
0976:                return true;
0977:            }
0978:
0979:            /**
0980:             * @see IClasspathEntry#getAccessRules()
0981:             */
0982:            public IAccessRule[] getAccessRules() {
0983:                if (this .accessRuleSet == null)
0984:                    return NO_ACCESS_RULES;
0985:                AccessRule[] rules = this .accessRuleSet.getAccessRules();
0986:                int length = rules.length;
0987:                if (length == 0)
0988:                    return NO_ACCESS_RULES;
0989:                IAccessRule[] result = new IAccessRule[length];
0990:                System.arraycopy(rules, 0, result, 0, length);
0991:                return result;
0992:            }
0993:
0994:            public AccessRuleSet getAccessRuleSet() {
0995:                return this .accessRuleSet;
0996:            }
0997:
0998:            /**
0999:             * @see IClasspathEntry
1000:             */
1001:            public int getContentKind() {
1002:                return this .contentKind;
1003:            }
1004:
1005:            /**
1006:             * @see IClasspathEntry
1007:             */
1008:            public int getEntryKind() {
1009:                return this .entryKind;
1010:            }
1011:
1012:            /**
1013:             * @see IClasspathEntry#getExclusionPatterns()
1014:             */
1015:            public IPath[] getExclusionPatterns() {
1016:                return this .exclusionPatterns;
1017:            }
1018:
1019:            public IClasspathAttribute[] getExtraAttributes() {
1020:                return this .extraAttributes;
1021:            }
1022:
1023:            private String[] getMessageTemplates() {
1024:                JavaModelManager manager = JavaModelManager
1025:                        .getJavaModelManager();
1026:                String[] result = new String[AccessRuleSet.MESSAGE_TEMPLATES_LENGTH];
1027:                if (this .entryKind == CPE_PROJECT
1028:                        || this .entryKind == CPE_SOURCE) { // can be remote source entry when reconciling
1029:                    result[0] = manager
1030:                            .intern(Messages
1031:                                    .bind(
1032:                                            org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_project,
1033:                                            new String[] {
1034:                                                    "{0}", getPath().segment(0) })); //$NON-NLS-1$
1035:                    result[1] = manager
1036:                            .intern(Messages
1037:                                    .bind(
1038:                                            org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_constructor_project,
1039:                                            new String[] {
1040:                                                    "{0}", getPath().segment(0) })); //$NON-NLS-1$
1041:                    result[2] = manager
1042:                            .intern(Messages
1043:                                    .bind(
1044:                                            org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_method_project,
1045:                                            new String[] {
1046:                                                    "{0}", "{1}", getPath().segment(0) })); //$NON-NLS-1$ //$NON-NLS-2$
1047:                    result[3] = manager
1048:                            .intern(Messages
1049:                                    .bind(
1050:                                            org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_field_project,
1051:                                            new String[] {
1052:                                                    "{0}", "{1}", getPath().segment(0) })); //$NON-NLS-1$ //$NON-NLS-2$
1053:                } else {
1054:                    IPath libPath = getPath();
1055:                    Object target = JavaModel.getTarget(ResourcesPlugin
1056:                            .getWorkspace().getRoot(), libPath, false);
1057:                    String pathString;
1058:                    if (target instanceof  java.io.File)
1059:                        pathString = libPath.toOSString();
1060:                    else
1061:                        pathString = libPath.makeRelative().toString();
1062:                    result[0] = manager
1063:                            .intern(Messages
1064:                                    .bind(
1065:                                            org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_library,
1066:                                            new String[] { "{0}", pathString })); //$NON-NLS-1$
1067:                    result[1] = manager
1068:                            .intern(Messages
1069:                                    .bind(
1070:                                            org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_constructor_library,
1071:                                            new String[] { "{0}", pathString })); //$NON-NLS-1$
1072:                    result[2] = manager
1073:                            .intern(Messages
1074:                                    .bind(
1075:                                            org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_method_library,
1076:                                            new String[] {
1077:                                                    "{0}", "{1}", pathString })); //$NON-NLS-1$ //$NON-NLS-2$
1078:                    result[3] = manager
1079:                            .intern(Messages
1080:                                    .bind(
1081:                                            org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_field_library,
1082:                                            new String[] {
1083:                                                    "{0}", "{1}", pathString })); //$NON-NLS-1$ //$NON-NLS-2$
1084:                }
1085:                return result;
1086:            }
1087:
1088:            /**
1089:             * @see IClasspathEntry#getExclusionPatterns()
1090:             */
1091:            public IPath[] getInclusionPatterns() {
1092:                return this .inclusionPatterns;
1093:            }
1094:
1095:            /**
1096:             * @see IClasspathEntry#getOutputLocation()
1097:             */
1098:            public IPath getOutputLocation() {
1099:                return this .specificOutputLocation;
1100:            }
1101:
1102:            /**
1103:             * @see IClasspathEntry
1104:             */
1105:            public IPath getPath() {
1106:                return this .path;
1107:            }
1108:
1109:            /**
1110:             * @see IClasspathEntry
1111:             */
1112:            public IPath getSourceAttachmentPath() {
1113:                return this .sourceAttachmentPath;
1114:            }
1115:
1116:            /**
1117:             * @see IClasspathEntry
1118:             */
1119:            public IPath getSourceAttachmentRootPath() {
1120:                return this .sourceAttachmentRootPath;
1121:            }
1122:
1123:            /**
1124:             * Returns the hash code for this classpath entry
1125:             */
1126:            public int hashCode() {
1127:                return this .path.hashCode();
1128:            }
1129:
1130:            /**
1131:             * @see IClasspathEntry#isExported()
1132:             */
1133:            public boolean isExported() {
1134:                return this .isExported;
1135:            }
1136:
1137:            public boolean isOptional() {
1138:                for (int i = 0, length = this .extraAttributes.length; i < length; i++) {
1139:                    IClasspathAttribute attribute = this .extraAttributes[i];
1140:                    if (IClasspathAttribute.OPTIONAL
1141:                            .equals(attribute.getName())
1142:                            && "true".equals(attribute.getValue())) //$NON-NLS-1$
1143:                        return true;
1144:                }
1145:                return false;
1146:            }
1147:
1148:            /**
1149:             * Returns the kind of a <code>PackageFragmentRoot</code> from its <code>String</code> form.
1150:             */
1151:            static int kindFromString(String kindStr) {
1152:
1153:                if (kindStr.equalsIgnoreCase("prj")) //$NON-NLS-1$
1154:                    return IClasspathEntry.CPE_PROJECT;
1155:                if (kindStr.equalsIgnoreCase("var")) //$NON-NLS-1$
1156:                    return IClasspathEntry.CPE_VARIABLE;
1157:                if (kindStr.equalsIgnoreCase("con")) //$NON-NLS-1$
1158:                    return IClasspathEntry.CPE_CONTAINER;
1159:                if (kindStr.equalsIgnoreCase("src")) //$NON-NLS-1$
1160:                    return IClasspathEntry.CPE_SOURCE;
1161:                if (kindStr.equalsIgnoreCase("lib")) //$NON-NLS-1$
1162:                    return IClasspathEntry.CPE_LIBRARY;
1163:                if (kindStr.equalsIgnoreCase("output")) //$NON-NLS-1$
1164:                    return ClasspathEntry.K_OUTPUT;
1165:                return -1;
1166:            }
1167:
1168:            /**
1169:             * Returns a <code>String</code> for the kind of a class path entry.
1170:             */
1171:            static String kindToString(int kind) {
1172:
1173:                switch (kind) {
1174:                case IClasspathEntry.CPE_PROJECT:
1175:                    return "src"; // backward compatibility //$NON-NLS-1$
1176:                case IClasspathEntry.CPE_SOURCE:
1177:                    return "src"; //$NON-NLS-1$
1178:                case IClasspathEntry.CPE_LIBRARY:
1179:                    return "lib"; //$NON-NLS-1$
1180:                case IClasspathEntry.CPE_VARIABLE:
1181:                    return "var"; //$NON-NLS-1$
1182:                case IClasspathEntry.CPE_CONTAINER:
1183:                    return "con"; //$NON-NLS-1$
1184:                case ClasspathEntry.K_OUTPUT:
1185:                    return "output"; //$NON-NLS-1$
1186:                default:
1187:                    return "unknown"; //$NON-NLS-1$
1188:                }
1189:            }
1190:
1191:            /*
1192:             * Backward compatibility: only accessible and non-accessible files are suported.
1193:             */
1194:            public static IAccessRule[] getAccessRules(IPath[] accessibleFiles,
1195:                    IPath[] nonAccessibleFiles) {
1196:                int accessibleFilesLength = accessibleFiles == null ? 0
1197:                        : accessibleFiles.length;
1198:                int nonAccessibleFilesLength = nonAccessibleFiles == null ? 0
1199:                        : nonAccessibleFiles.length;
1200:                int length = accessibleFilesLength + nonAccessibleFilesLength;
1201:                if (length == 0)
1202:                    return null;
1203:                IAccessRule[] accessRules = new IAccessRule[length];
1204:                for (int i = 0; i < accessibleFilesLength; i++) {
1205:                    accessRules[i] = JavaCore.newAccessRule(accessibleFiles[i],
1206:                            IAccessRule.K_ACCESSIBLE);
1207:                }
1208:                for (int i = 0; i < nonAccessibleFilesLength; i++) {
1209:                    accessRules[accessibleFilesLength + i] = JavaCore
1210:                            .newAccessRule(nonAccessibleFiles[i],
1211:                                    IAccessRule.K_NON_ACCESSIBLE);
1212:                }
1213:                return accessRules;
1214:            }
1215:
1216:            /**
1217:             * Returns a printable representation of this classpath entry.
1218:             */
1219:            public String toString() {
1220:                StringBuffer buffer = new StringBuffer();
1221:                buffer.append(String.valueOf(getPath()));
1222:                buffer.append('[');
1223:                switch (getEntryKind()) {
1224:                case IClasspathEntry.CPE_LIBRARY:
1225:                    buffer.append("CPE_LIBRARY"); //$NON-NLS-1$
1226:                    break;
1227:                case IClasspathEntry.CPE_PROJECT:
1228:                    buffer.append("CPE_PROJECT"); //$NON-NLS-1$
1229:                    break;
1230:                case IClasspathEntry.CPE_SOURCE:
1231:                    buffer.append("CPE_SOURCE"); //$NON-NLS-1$
1232:                    break;
1233:                case IClasspathEntry.CPE_VARIABLE:
1234:                    buffer.append("CPE_VARIABLE"); //$NON-NLS-1$
1235:                    break;
1236:                case IClasspathEntry.CPE_CONTAINER:
1237:                    buffer.append("CPE_CONTAINER"); //$NON-NLS-1$
1238:                    break;
1239:                }
1240:                buffer.append("]["); //$NON-NLS-1$
1241:                switch (getContentKind()) {
1242:                case IPackageFragmentRoot.K_BINARY:
1243:                    buffer.append("K_BINARY"); //$NON-NLS-1$
1244:                    break;
1245:                case IPackageFragmentRoot.K_SOURCE:
1246:                    buffer.append("K_SOURCE"); //$NON-NLS-1$
1247:                    break;
1248:                case ClasspathEntry.K_OUTPUT:
1249:                    buffer.append("K_OUTPUT"); //$NON-NLS-1$
1250:                    break;
1251:                }
1252:                buffer.append(']');
1253:                if (getSourceAttachmentPath() != null) {
1254:                    buffer.append("[sourcePath:"); //$NON-NLS-1$
1255:                    buffer.append(getSourceAttachmentPath());
1256:                    buffer.append(']');
1257:                }
1258:                if (getSourceAttachmentRootPath() != null) {
1259:                    buffer.append("[rootPath:"); //$NON-NLS-1$
1260:                    buffer.append(getSourceAttachmentRootPath());
1261:                    buffer.append(']');
1262:                }
1263:                buffer.append("[isExported:"); //$NON-NLS-1$
1264:                buffer.append(this .isExported);
1265:                buffer.append(']');
1266:                IPath[] patterns = this .inclusionPatterns;
1267:                int length;
1268:                if ((length = patterns == null ? 0 : patterns.length) > 0) {
1269:                    buffer.append("[including:"); //$NON-NLS-1$
1270:                    for (int i = 0; i < length; i++) {
1271:                        buffer.append(patterns[i]);
1272:                        if (i != length - 1) {
1273:                            buffer.append('|');
1274:                        }
1275:                    }
1276:                    buffer.append(']');
1277:                }
1278:                patterns = this .exclusionPatterns;
1279:                if ((length = patterns == null ? 0 : patterns.length) > 0) {
1280:                    buffer.append("[excluding:"); //$NON-NLS-1$
1281:                    for (int i = 0; i < length; i++) {
1282:                        buffer.append(patterns[i]);
1283:                        if (i != length - 1) {
1284:                            buffer.append('|');
1285:                        }
1286:                    }
1287:                    buffer.append(']');
1288:                }
1289:                if (this .accessRuleSet != null) {
1290:                    buffer.append('[');
1291:                    buffer.append(this .accessRuleSet
1292:                            .toString(false/*on one line*/));
1293:                    buffer.append(']');
1294:                }
1295:                if (this .entryKind == CPE_PROJECT) {
1296:                    buffer.append("[combine access rules:"); //$NON-NLS-1$
1297:                    buffer.append(this .combineAccessRules);
1298:                    buffer.append(']');
1299:                }
1300:                if (getOutputLocation() != null) {
1301:                    buffer.append("[output:"); //$NON-NLS-1$
1302:                    buffer.append(getOutputLocation());
1303:                    buffer.append(']');
1304:                }
1305:                if ((length = this .extraAttributes == null ? 0
1306:                        : this .extraAttributes.length) > 0) {
1307:                    buffer.append("[attributes:"); //$NON-NLS-1$
1308:                    for (int i = 0; i < length; i++) {
1309:                        buffer.append(this .extraAttributes[i]);
1310:                        if (i != length - 1) {
1311:                            buffer.append(',');
1312:                        }
1313:                    }
1314:                    buffer.append(']');
1315:                }
1316:                return buffer.toString();
1317:            }
1318:
1319:            /**
1320:             * Answers an ID which is used to distinguish entries during package
1321:             * fragment root computations
1322:             */
1323:            public String rootID() {
1324:
1325:                if (this .rootID == null) {
1326:                    switch (this .entryKind) {
1327:                    case IClasspathEntry.CPE_LIBRARY:
1328:                        this .rootID = "[LIB]" + this .path; //$NON-NLS-1$
1329:                        break;
1330:                    case IClasspathEntry.CPE_PROJECT:
1331:                        this .rootID = "[PRJ]" + this .path; //$NON-NLS-1$
1332:                        break;
1333:                    case IClasspathEntry.CPE_SOURCE:
1334:                        this .rootID = "[SRC]" + this .path; //$NON-NLS-1$
1335:                        break;
1336:                    case IClasspathEntry.CPE_VARIABLE:
1337:                        this .rootID = "[VAR]" + this .path; //$NON-NLS-1$
1338:                        break;
1339:                    case IClasspathEntry.CPE_CONTAINER:
1340:                        this .rootID = "[CON]" + this .path; //$NON-NLS-1$
1341:                        break;
1342:                    default:
1343:                        this .rootID = ""; //$NON-NLS-1$
1344:                        break;
1345:                    }
1346:                }
1347:                return this .rootID;
1348:            }
1349:
1350:            /**
1351:             * @see IClasspathEntry
1352:             * @deprecated
1353:             */
1354:            public IClasspathEntry getResolvedEntry() {
1355:
1356:                return JavaCore.getResolvedClasspathEntry(this );
1357:            }
1358:
1359:            /**
1360:             * Validate a given classpath and output location for a project, using the following rules:
1361:             * <ul>
1362:             *   <li> Classpath entries cannot collide with each other; that is, all entry paths must be unique.
1363:             *   <li> The project output location path cannot be null, must be absolute and located inside the project.
1364:             *   <li> Specific output locations (specified on source entries) can be null, if not they must be located inside the project,
1365:             *   <li> A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself).
1366:             *   <li> Classpath entries or output locations cannot coincidate or be nested in each other, except for the following scenarii listed below:
1367:             *      <ul><li> A source folder can coincidate with its own output location, in which case this output can then contain library archives.
1368:             *                     However, a specific output location cannot coincidate with any library or a distinct source folder than the one referring to it. </li>
1369:             *              <li> A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one. </li>
1370:             * 			<li> An output location can be nested in a source folder, if the source folder coincidates with the project itself, or if the output
1371:             * 					location is excluded from the source folder. </li>
1372:             *      </ul>
1373:             * </ul>
1374:             *
1375:             *  Note that the classpath entries are not validated automatically. Only bound variables or containers are considered
1376:             *  in the checking process (this allows to perform a consistency check on a classpath which has references to
1377:             *  yet non existing projects, folders, ...).
1378:             *  <p>
1379:             *  This validation is intended to anticipate classpath issues prior to assigning it to a project. In particular, it will automatically
1380:             *  be performed during the classpath setting operation (if validation fails, the classpath setting will not complete).
1381:             *  <p>
1382:             * @param javaProject the given java project
1383:             * @param rawClasspath a given classpath
1384:             * @param projectOutputLocation a given output location
1385:             * @return a status object with code <code>IStatus.OK</code> if
1386:             *		the given classpath and output location are compatible, otherwise a status
1387:             *		object indicating what is wrong with the classpath or output location
1388:             */
1389:            public static IJavaModelStatus validateClasspath(
1390:                    IJavaProject javaProject, IClasspathEntry[] rawClasspath,
1391:                    IPath projectOutputLocation) {
1392:
1393:                IProject project = javaProject.getProject();
1394:                IPath projectPath = project.getFullPath();
1395:                String projectName = javaProject.getElementName();
1396:
1397:                /* validate output location */
1398:                if (projectOutputLocation == null) {
1399:                    return new JavaModelStatus(
1400:                            IJavaModelStatusConstants.NULL_PATH);
1401:                }
1402:                if (projectOutputLocation.isAbsolute()) {
1403:                    if (!projectPath.isPrefixOf(projectOutputLocation)) {
1404:                        return new JavaModelStatus(
1405:                                IJavaModelStatusConstants.PATH_OUTSIDE_PROJECT,
1406:                                javaProject, projectOutputLocation.toString());
1407:                    }
1408:                } else {
1409:                    return new JavaModelStatus(
1410:                            IJavaModelStatusConstants.RELATIVE_PATH,
1411:                            projectOutputLocation);
1412:                }
1413:
1414:                boolean hasSource = false;
1415:                boolean hasLibFolder = false;
1416:
1417:                // tolerate null path, it will be reset to default
1418:                if (rawClasspath == null)
1419:                    return JavaModelStatus.VERIFIED_OK;
1420:
1421:                // retrieve resolved classpath
1422:                IClasspathEntry[] classpath;
1423:                try {
1424:                    classpath = ((JavaProject) javaProject)
1425:                            .resolveClasspath(rawClasspath);
1426:                } catch (JavaModelException e) {
1427:                    return e.getJavaModelStatus();
1428:                }
1429:                int length = classpath.length;
1430:
1431:                int outputCount = 1;
1432:                IPath[] outputLocations = new IPath[length + 1];
1433:                boolean[] allowNestingInOutputLocations = new boolean[length + 1];
1434:                outputLocations[0] = projectOutputLocation;
1435:
1436:                // retrieve and check output locations
1437:                IPath potentialNestedOutput = null; // for error reporting purpose
1438:                int sourceEntryCount = 0;
1439:                boolean disableExclusionPatterns = JavaCore.DISABLED
1440:                        .equals(javaProject
1441:                                .getOption(
1442:                                        JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS,
1443:                                        true));
1444:                boolean disableCustomOutputLocations = JavaCore.DISABLED
1445:                        .equals(javaProject
1446:                                .getOption(
1447:                                        JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS,
1448:                                        true));
1449:
1450:                for (int i = 0; i < length; i++) {
1451:                    IClasspathEntry resolvedEntry = classpath[i];
1452:                    if (disableExclusionPatterns
1453:                            && ((resolvedEntry.getInclusionPatterns() != null && resolvedEntry
1454:                                    .getInclusionPatterns().length > 0) || (resolvedEntry
1455:                                    .getExclusionPatterns() != null && resolvedEntry
1456:                                    .getExclusionPatterns().length > 0))) {
1457:                        return new JavaModelStatus(
1458:                                IJavaModelStatusConstants.DISABLED_CP_EXCLUSION_PATTERNS,
1459:                                javaProject, resolvedEntry.getPath());
1460:                    }
1461:                    switch (resolvedEntry.getEntryKind()) {
1462:                    case IClasspathEntry.CPE_SOURCE:
1463:                        sourceEntryCount++;
1464:
1465:                        IPath customOutput;
1466:                        if ((customOutput = resolvedEntry.getOutputLocation()) != null) {
1467:
1468:                            if (disableCustomOutputLocations) {
1469:                                return new JavaModelStatus(
1470:                                        IJavaModelStatusConstants.DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS,
1471:                                        javaProject, resolvedEntry.getPath());
1472:                            }
1473:                            // ensure custom output is in project
1474:                            if (customOutput.isAbsolute()) {
1475:                                if (!javaProject.getPath().isPrefixOf(
1476:                                        customOutput)) {
1477:                                    return new JavaModelStatus(
1478:                                            IJavaModelStatusConstants.PATH_OUTSIDE_PROJECT,
1479:                                            javaProject, customOutput
1480:                                                    .toString());
1481:                                }
1482:                            } else {
1483:                                return new JavaModelStatus(
1484:                                        IJavaModelStatusConstants.RELATIVE_PATH,
1485:                                        customOutput);
1486:                            }
1487:
1488:                            // ensure custom output doesn't conflict with other outputs
1489:                            // check exact match
1490:                            if (Util.indexOfMatchingPath(customOutput,
1491:                                    outputLocations, outputCount) != -1) {
1492:                                continue; // already found
1493:                            }
1494:                            // accumulate all outputs, will check nesting once all available (to handle ordering issues)
1495:                            outputLocations[outputCount++] = customOutput;
1496:                        }
1497:                    }
1498:                }
1499:                // check nesting across output locations
1500:                for (int i = 1 /*no check for default output*/; i < outputCount; i++) {
1501:                    IPath customOutput = outputLocations[i];
1502:                    int index;
1503:                    // check nesting
1504:                    if ((index = Util.indexOfEnclosingPath(customOutput,
1505:                            outputLocations, outputCount)) != -1
1506:                            && index != i) {
1507:                        if (index == 0) {
1508:                            // custom output is nested in project's output: need to check if all source entries have a custom
1509:                            // output before complaining
1510:                            if (potentialNestedOutput == null)
1511:                                potentialNestedOutput = customOutput;
1512:                        } else {
1513:                            return new JavaModelStatus(
1514:                                    IJavaModelStatusConstants.INVALID_CLASSPATH,
1515:                                    Messages
1516:                                            .bind(
1517:                                                    Messages.classpath_cannotNestOutputInOutput,
1518:                                                    new String[] {
1519:                                                            customOutput
1520:                                                                    .makeRelative()
1521:                                                                    .toString(),
1522:                                                            outputLocations[index]
1523:                                                                    .makeRelative()
1524:                                                                    .toString() }));
1525:                        }
1526:                    }
1527:                }
1528:                // allow custom output nesting in project's output if all source entries have a custom output
1529:                if (sourceEntryCount <= outputCount - 1) {
1530:                    allowNestingInOutputLocations[0] = true;
1531:                } else if (potentialNestedOutput != null) {
1532:                    return new JavaModelStatus(
1533:                            IJavaModelStatusConstants.INVALID_CLASSPATH,
1534:                            Messages
1535:                                    .bind(
1536:                                            Messages.classpath_cannotNestOutputInOutput,
1537:                                            new String[] {
1538:                                                    potentialNestedOutput
1539:                                                            .makeRelative()
1540:                                                            .toString(),
1541:                                                    outputLocations[0]
1542:                                                            .makeRelative()
1543:                                                            .toString() }));
1544:                }
1545:
1546:                for (int i = 0; i < length; i++) {
1547:                    IClasspathEntry resolvedEntry = classpath[i];
1548:                    IPath path = resolvedEntry.getPath();
1549:                    int index;
1550:                    switch (resolvedEntry.getEntryKind()) {
1551:
1552:                    case IClasspathEntry.CPE_SOURCE:
1553:                        hasSource = true;
1554:                        if ((index = Util.indexOfMatchingPath(path,
1555:                                outputLocations, outputCount)) != -1) {
1556:                            allowNestingInOutputLocations[index] = true;
1557:                        }
1558:                        break;
1559:
1560:                    case IClasspathEntry.CPE_LIBRARY:
1561:                        hasLibFolder |= !org.eclipse.jdt.internal.compiler.util.Util
1562:                                .isArchiveFileName(path.lastSegment());
1563:                        if ((index = Util.indexOfMatchingPath(path,
1564:                                outputLocations, outputCount)) != -1) {
1565:                            allowNestingInOutputLocations[index] = true;
1566:                        }
1567:                        break;
1568:                    }
1569:                }
1570:                if (!hasSource && !hasLibFolder) { // if no source and no lib folder, then allowed
1571:                    for (int i = 0; i < outputCount; i++)
1572:                        allowNestingInOutputLocations[i] = true;
1573:                }
1574:
1575:                HashSet pathes = new HashSet(length);
1576:
1577:                // check all entries
1578:                for (int i = 0; i < length; i++) {
1579:                    IClasspathEntry entry = classpath[i];
1580:                    if (entry == null)
1581:                        continue;
1582:                    IPath entryPath = entry.getPath();
1583:                    int kind = entry.getEntryKind();
1584:
1585:                    // Build some common strings for status message
1586:                    boolean isProjectRelative = projectName.equals(entryPath
1587:                            .segment(0));
1588:                    String entryPathMsg = isProjectRelative ? entryPath
1589:                            .removeFirstSegments(1).toString() : entryPath
1590:                            .makeRelative().toString();
1591:
1592:                    // complain if duplicate path
1593:                    if (!pathes.add(entryPath)) {
1594:                        return new JavaModelStatus(
1595:                                IJavaModelStatusConstants.NAME_COLLISION,
1596:                                Messages.bind(
1597:                                        Messages.classpath_duplicateEntryPath,
1598:                                        new String[] { entryPathMsg,
1599:                                                projectName }));
1600:                    }
1601:                    // no further check if entry coincidates with project or output location
1602:                    if (entryPath.equals(projectPath)) {
1603:                        // complain if self-referring project entry
1604:                        if (kind == IClasspathEntry.CPE_PROJECT) {
1605:                            return new JavaModelStatus(
1606:                                    IJavaModelStatusConstants.INVALID_PATH,
1607:                                    Messages
1608:                                            .bind(
1609:                                                    Messages.classpath_cannotReferToItself,
1610:                                                    entryPath.makeRelative()
1611:                                                            .toString()));
1612:                        }
1613:                        // tolerate nesting output in src if src==prj
1614:                        continue;
1615:                    }
1616:
1617:                    // allow nesting source entries in each other as long as the outer entry excludes the inner one
1618:                    if (kind == IClasspathEntry.CPE_SOURCE
1619:                            || (kind == IClasspathEntry.CPE_LIBRARY && !org.eclipse.jdt.internal.compiler.util.Util
1620:                                    .isArchiveFileName(entryPath.lastSegment()))) {
1621:                        for (int j = 0; j < classpath.length; j++) {
1622:                            IClasspathEntry otherEntry = classpath[j];
1623:                            if (otherEntry == null)
1624:                                continue;
1625:                            int otherKind = otherEntry.getEntryKind();
1626:                            IPath otherPath = otherEntry.getPath();
1627:                            if (entry != otherEntry
1628:                                    && (otherKind == IClasspathEntry.CPE_SOURCE || (otherKind == IClasspathEntry.CPE_LIBRARY && !org.eclipse.jdt.internal.compiler.util.Util
1629:                                            .isArchiveFileName(otherPath
1630:                                                    .lastSegment())))) {
1631:                                char[][] inclusionPatterns, exclusionPatterns;
1632:                                if (otherPath.isPrefixOf(entryPath)
1633:                                        && !otherPath.equals(entryPath)
1634:                                        && !Util
1635:                                                .isExcluded(
1636:                                                        entryPath.append("*"), inclusionPatterns = ((ClasspathEntry) otherEntry).fullInclusionPatternChars(), exclusionPatterns = ((ClasspathEntry) otherEntry).fullExclusionPatternChars(), false)) { //$NON-NLS-1$
1637:                                    String exclusionPattern = entryPath
1638:                                            .removeFirstSegments(
1639:                                                    otherPath.segmentCount())
1640:                                            .segment(0);
1641:                                    if (Util.isExcluded(entryPath,
1642:                                            inclusionPatterns,
1643:                                            exclusionPatterns, false)) {
1644:                                        return new JavaModelStatus(
1645:                                                IJavaModelStatusConstants.INVALID_CLASSPATH,
1646:                                                Messages
1647:                                                        .bind(
1648:                                                                Messages.classpath_mustEndWithSlash,
1649:                                                                new String[] {
1650:                                                                        exclusionPattern,
1651:                                                                        entryPath
1652:                                                                                .makeRelative()
1653:                                                                                .toString() }));
1654:                                    } else {
1655:                                        if (otherKind == IClasspathEntry.CPE_SOURCE) {
1656:                                            exclusionPattern += '/';
1657:                                            if (!disableExclusionPatterns) {
1658:                                                return new JavaModelStatus(
1659:                                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
1660:                                                        Messages
1661:                                                                .bind(
1662:                                                                        Messages.classpath_cannotNestEntryInEntry,
1663:                                                                        new String[] {
1664:                                                                                entryPath
1665:                                                                                        .makeRelative()
1666:                                                                                        .toString(),
1667:                                                                                otherEntry
1668:                                                                                        .getPath()
1669:                                                                                        .makeRelative()
1670:                                                                                        .toString(),
1671:                                                                                exclusionPattern }));
1672:                                            } else {
1673:                                                return new JavaModelStatus(
1674:                                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
1675:                                                        Messages
1676:                                                                .bind(
1677:                                                                        Messages.classpath_cannotNestEntryInEntryNoExclusion,
1678:                                                                        new String[] {
1679:                                                                                entryPath
1680:                                                                                        .makeRelative()
1681:                                                                                        .toString(),
1682:                                                                                otherEntry
1683:                                                                                        .getPath()
1684:                                                                                        .makeRelative()
1685:                                                                                        .toString(),
1686:                                                                                exclusionPattern }));
1687:                                            }
1688:                                        } else {
1689:                                            return new JavaModelStatus(
1690:                                                    IJavaModelStatusConstants.INVALID_CLASSPATH,
1691:                                                    Messages
1692:                                                            .bind(
1693:                                                                    Messages.classpath_cannotNestEntryInLibrary,
1694:                                                                    new String[] {
1695:                                                                            entryPath
1696:                                                                                    .makeRelative()
1697:                                                                                    .toString(),
1698:                                                                            otherEntry
1699:                                                                                    .getPath()
1700:                                                                                    .makeRelative()
1701:                                                                                    .toString() }));
1702:                                        }
1703:                                    }
1704:                                }
1705:                            }
1706:                        }
1707:                    }
1708:
1709:                    // prevent nesting output location inside entry unless enclosing is a source entry which explicitly exclude the output location
1710:                    char[][] inclusionPatterns = ((ClasspathEntry) entry)
1711:                            .fullInclusionPatternChars();
1712:                    char[][] exclusionPatterns = ((ClasspathEntry) entry)
1713:                            .fullExclusionPatternChars();
1714:                    for (int j = 0; j < outputCount; j++) {
1715:                        IPath currentOutput = outputLocations[j];
1716:                        if (entryPath.equals(currentOutput))
1717:                            continue;
1718:                        if (entryPath.isPrefixOf(currentOutput)) {
1719:                            if (kind != IClasspathEntry.CPE_SOURCE
1720:                                    || !Util.isExcluded(currentOutput,
1721:                                            inclusionPatterns,
1722:                                            exclusionPatterns, true)) {
1723:                                return new JavaModelStatus(
1724:                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
1725:                                        Messages
1726:                                                .bind(
1727:                                                        Messages.classpath_cannotNestOutputInEntry,
1728:                                                        new String[] {
1729:                                                                currentOutput
1730:                                                                        .makeRelative()
1731:                                                                        .toString(),
1732:                                                                entryPath
1733:                                                                        .makeRelative()
1734:                                                                        .toString() }));
1735:                            }
1736:                        }
1737:                    }
1738:
1739:                    // prevent nesting entry inside output location - when distinct from project or a source folder
1740:                    for (int j = 0; j < outputCount; j++) {
1741:                        if (allowNestingInOutputLocations[j])
1742:                            continue;
1743:                        IPath currentOutput = outputLocations[j];
1744:                        if (currentOutput.isPrefixOf(entryPath)) {
1745:                            return new JavaModelStatus(
1746:                                    IJavaModelStatusConstants.INVALID_CLASSPATH,
1747:                                    Messages
1748:                                            .bind(
1749:                                                    Messages.classpath_cannotNestEntryInOutput,
1750:                                                    new String[] {
1751:                                                            entryPath
1752:                                                                    .makeRelative()
1753:                                                                    .toString(),
1754:                                                            currentOutput
1755:                                                                    .makeRelative()
1756:                                                                    .toString() }));
1757:                        }
1758:                    }
1759:                }
1760:                // ensure that no specific output is coincidating with another source folder (only allowed if matching current source folder)
1761:                // 36465 - for 2.0 backward compatibility, only check specific output locations (the default can still coincidate)
1762:                // perform one separate iteration so as to not take precedence over previously checked scenarii (in particular should
1763:                // diagnose nesting source folder issue before this one, for example, [src]"Project/", [src]"Project/source/" and output="Project/" should
1764:                // first complain about missing exclusion pattern
1765:                for (int i = 0; i < length; i++) {
1766:                    IClasspathEntry entry = classpath[i];
1767:                    if (entry == null)
1768:                        continue;
1769:                    IPath entryPath = entry.getPath();
1770:                    int kind = entry.getEntryKind();
1771:
1772:                    // Build some common strings for status message
1773:                    boolean isProjectRelative = projectName.equals(entryPath
1774:                            .segment(0));
1775:                    String entryPathMsg = isProjectRelative ? entryPath
1776:                            .removeFirstSegments(1).toString() : entryPath
1777:                            .makeRelative().toString();
1778:
1779:                    if (kind == IClasspathEntry.CPE_SOURCE) {
1780:                        IPath output = entry.getOutputLocation();
1781:                        if (output == null)
1782:                            continue; // 36465 - for 2.0 backward compatibility, only check specific output locations (the default can still coincidate)
1783:                        // if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output)
1784:                        for (int j = 0; j < length; j++) {
1785:                            IClasspathEntry otherEntry = classpath[j];
1786:                            if (otherEntry == entry)
1787:                                continue;
1788:
1789:                            // Build some common strings for status message
1790:                            boolean opStartsWithProject = projectName
1791:                                    .equals(otherEntry.getPath().segment(0));
1792:                            String otherPathMsg = opStartsWithProject ? otherEntry
1793:                                    .getPath().removeFirstSegments(1)
1794:                                    .toString()
1795:                                    : otherEntry.getPath().makeRelative()
1796:                                            .toString();
1797:
1798:                            switch (otherEntry.getEntryKind()) {
1799:                            case IClasspathEntry.CPE_SOURCE:
1800:                                if (otherEntry.getPath().equals(output)) {
1801:                                    return new JavaModelStatus(
1802:                                            IJavaModelStatusConstants.INVALID_CLASSPATH,
1803:                                            Messages
1804:                                                    .bind(
1805:                                                            Messages.classpath_cannotUseDistinctSourceFolderAsOutput,
1806:                                                            new String[] {
1807:                                                                    entryPathMsg,
1808:                                                                    otherPathMsg,
1809:                                                                    projectName }));
1810:                                }
1811:                                break;
1812:                            case IClasspathEntry.CPE_LIBRARY:
1813:                                if (otherEntry.getPath().equals(output)) {
1814:                                    return new JavaModelStatus(
1815:                                            IJavaModelStatusConstants.INVALID_CLASSPATH,
1816:                                            Messages
1817:                                                    .bind(
1818:                                                            Messages.classpath_cannotUseLibraryAsOutput,
1819:                                                            new String[] {
1820:                                                                    entryPathMsg,
1821:                                                                    otherPathMsg,
1822:                                                                    projectName }));
1823:                                }
1824:                            }
1825:                        }
1826:                    }
1827:                }
1828:                return JavaModelStatus.VERIFIED_OK;
1829:            }
1830:
1831:            /**
1832:             * Returns a Java model status describing the problem related to this classpath entry if any,
1833:             * a status object with code <code>IStatus.OK</code> if the entry is fine (that is, if the
1834:             * given classpath entry denotes a valid element to be referenced onto a classpath).
1835:             *
1836:             * @param project the given java project
1837:             * @param entry the given classpath entry
1838:             * @param checkSourceAttachment a flag to determine if source attachement should be checked
1839:             * @param recurseInContainers flag indicating whether validation should be applied to container entries recursively
1840:             * @return a java model status describing the problem related to this classpath entry if any, a status object with code <code>IStatus.OK</code> if the entry is fine
1841:             */
1842:            public static IJavaModelStatus validateClasspathEntry(
1843:                    IJavaProject project, IClasspathEntry entry,
1844:                    boolean checkSourceAttachment, boolean recurseInContainers) {
1845:
1846:                IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace()
1847:                        .getRoot();
1848:                IPath path = entry.getPath();
1849:
1850:                // Build some common strings for status message
1851:                String projectName = project.getElementName();
1852:                boolean pathStartsWithProject = projectName.equals(path
1853:                        .segment(0));
1854:                String entryPathMsg = pathStartsWithProject ? path
1855:                        .removeFirstSegments(1).makeRelative().toString()
1856:                        : path.toString();
1857:
1858:                switch (entry.getEntryKind()) {
1859:
1860:                // container entry check
1861:                case IClasspathEntry.CPE_CONTAINER:
1862:                    if (path.segmentCount() >= 1) {
1863:                        try {
1864:                            IClasspathContainer container = JavaModelManager
1865:                                    .getJavaModelManager()
1866:                                    .getClasspathContainer(path, project);
1867:                            // container retrieval is performing validation check on container entry kinds.
1868:                            if (container == null) {
1869:                                return new JavaModelStatus(
1870:                                        IJavaModelStatusConstants.CP_CONTAINER_PATH_UNBOUND,
1871:                                        project, path);
1872:                            } else if (container == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
1873:                                // Validate extra attributes
1874:                                IClasspathAttribute[] extraAttributes = entry
1875:                                        .getExtraAttributes();
1876:                                if (extraAttributes != null) {
1877:                                    int length = extraAttributes.length;
1878:                                    HashSet set = new HashSet(length);
1879:                                    for (int i = 0; i < length; i++) {
1880:                                        String attName = extraAttributes[i]
1881:                                                .getName();
1882:                                        if (!set.add(attName)) {
1883:                                            return new JavaModelStatus(
1884:                                                    IJavaModelStatusConstants.NAME_COLLISION,
1885:                                                    Messages
1886:                                                            .bind(
1887:                                                                    Messages.classpath_duplicateEntryExtraAttribute,
1888:                                                                    new String[] {
1889:                                                                            attName,
1890:                                                                            entryPathMsg,
1891:                                                                            projectName }));
1892:                                        }
1893:                                    }
1894:                                }
1895:                                // don't create a marker if initialization is in progress (case of cp initialization batching)
1896:                                return JavaModelStatus.VERIFIED_OK;
1897:                            }
1898:                            IClasspathEntry[] containerEntries = container
1899:                                    .getClasspathEntries();
1900:                            if (containerEntries != null) {
1901:                                for (int i = 0, length = containerEntries.length; i < length; i++) {
1902:                                    IClasspathEntry containerEntry = containerEntries[i];
1903:                                    int kind = containerEntry == null ? 0
1904:                                            : containerEntry.getEntryKind();
1905:                                    if (containerEntry == null
1906:                                            || kind == IClasspathEntry.CPE_SOURCE
1907:                                            || kind == IClasspathEntry.CPE_VARIABLE
1908:                                            || kind == IClasspathEntry.CPE_CONTAINER) {
1909:                                        String description = container
1910:                                                .getDescription();
1911:                                        if (description == null)
1912:                                            description = path.makeRelative()
1913:                                                    .toString();
1914:                                        return new JavaModelStatus(
1915:                                                IJavaModelStatusConstants.INVALID_CP_CONTAINER_ENTRY,
1916:                                                project, path);
1917:                                    }
1918:                                    if (recurseInContainers) {
1919:                                        IJavaModelStatus containerEntryStatus = validateClasspathEntry(
1920:                                                project, containerEntry,
1921:                                                checkSourceAttachment,
1922:                                                recurseInContainers);
1923:                                        if (!containerEntryStatus.isOK()) {
1924:                                            return containerEntryStatus;
1925:                                        }
1926:                                    }
1927:                                }
1928:                            }
1929:                        } catch (JavaModelException e) {
1930:                            return new JavaModelStatus(e);
1931:                        }
1932:                    } else {
1933:                        return new JavaModelStatus(
1934:                                IJavaModelStatusConstants.INVALID_CLASSPATH,
1935:                                Messages
1936:                                        .bind(
1937:                                                Messages.classpath_illegalContainerPath,
1938:                                                new String[] { entryPathMsg,
1939:                                                        projectName }));
1940:                    }
1941:                    break;
1942:
1943:                // variable entry check
1944:                case IClasspathEntry.CPE_VARIABLE:
1945:                    if (path.segmentCount() >= 1) {
1946:                        try {
1947:                            entry = JavaCore.getResolvedClasspathEntry(entry);
1948:                        } catch (AssertionFailedException e) {
1949:                            // Catch the assertion failure and throw java model exception instead
1950:                            // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55992
1951:                            return new JavaModelStatus(
1952:                                    IJavaModelStatusConstants.INVALID_PATH, e
1953:                                            .getMessage());
1954:                        }
1955:                        if (entry == null) {
1956:                            return new JavaModelStatus(
1957:                                    IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND,
1958:                                    project, path);
1959:                        }
1960:
1961:                        // get validation status
1962:                        IJavaModelStatus status = validateClasspathEntry(
1963:                                project, entry, checkSourceAttachment,
1964:                                recurseInContainers);
1965:                        if (!status.isOK())
1966:                            return status;
1967:
1968:                        // return deprecation status if any
1969:                        String variableName = path.segment(0);
1970:                        String deprecatedMessage = JavaCore
1971:                                .getClasspathVariableDeprecationMessage(variableName);
1972:                        if (deprecatedMessage != null) {
1973:                            return new JavaModelStatus(
1974:                                    IStatus.WARNING,
1975:                                    IJavaModelStatusConstants.DEPRECATED_VARIABLE,
1976:                                    project, path, deprecatedMessage);
1977:                        }
1978:                        return status;
1979:                    } else {
1980:                        return new JavaModelStatus(
1981:                                IJavaModelStatusConstants.INVALID_CLASSPATH,
1982:                                Messages.bind(
1983:                                        Messages.classpath_illegalVariablePath,
1984:                                        new String[] { entryPathMsg,
1985:                                                projectName }));
1986:                    }
1987:
1988:                    // library entry check
1989:                case IClasspathEntry.CPE_LIBRARY:
1990:                    if (path.isAbsolute() && !path.isEmpty()) {
1991:                        IPath sourceAttachment = entry
1992:                                .getSourceAttachmentPath();
1993:                        Object target = JavaModel.getTarget(workspaceRoot,
1994:                                path, true);
1995:                        if (target != null
1996:                                && !JavaCore.IGNORE.equals(project.getOption(
1997:                                        JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL,
1998:                                        true))) {
1999:                            long projectTargetJDK = CompilerOptions
2000:                                    .versionToJdkLevel(project
2001:                                            .getOption(
2002:                                                    JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
2003:                                                    true));
2004:                            long libraryJDK = Util.getJdkLevel(target);
2005:                            if (libraryJDK != 0
2006:                                    && libraryJDK > projectTargetJDK) {
2007:                                return new JavaModelStatus(
2008:                                        IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL,
2009:                                        project,
2010:                                        path,
2011:                                        CompilerOptions
2012:                                                .versionFromJdkLevel(libraryJDK));
2013:                            }
2014:                        }
2015:                        if (target instanceof  IResource) {
2016:                            IResource resolvedResource = (IResource) target;
2017:                            switch (resolvedResource.getType()) {
2018:                            case IResource.FILE:
2019:                                if (org.eclipse.jdt.internal.compiler.util.Util
2020:                                        .isArchiveFileName(resolvedResource
2021:                                                .getName())) {
2022:                                    if (checkSourceAttachment
2023:                                            && sourceAttachment != null
2024:                                            && !sourceAttachment.isEmpty()
2025:                                            && JavaModel.getTarget(
2026:                                                    workspaceRoot,
2027:                                                    sourceAttachment, true) == null) {
2028:                                        return new JavaModelStatus(
2029:                                                IJavaModelStatusConstants.INVALID_CLASSPATH,
2030:                                                Messages
2031:                                                        .bind(
2032:                                                                Messages.classpath_unboundSourceAttachment,
2033:                                                                new String[] {
2034:                                                                        sourceAttachment
2035:                                                                                .toString(),
2036:                                                                        path
2037:                                                                                .toString(),
2038:                                                                        projectName }));
2039:                                    }
2040:                                } else {
2041:                                    return new JavaModelStatus(
2042:                                            IJavaModelStatusConstants.INVALID_CLASSPATH,
2043:                                            Messages
2044:                                                    .bind(
2045:                                                            Messages.classpath_illegalLibraryArchive,
2046:                                                            new String[] {
2047:                                                                    entryPathMsg,
2048:                                                                    projectName }));
2049:                                }
2050:                                break;
2051:                            case IResource.FOLDER: // internal binary folder
2052:                                if (checkSourceAttachment
2053:                                        && sourceAttachment != null
2054:                                        && !sourceAttachment.isEmpty()
2055:                                        && JavaModel.getTarget(workspaceRoot,
2056:                                                sourceAttachment, true) == null) {
2057:                                    return new JavaModelStatus(
2058:                                            IJavaModelStatusConstants.INVALID_CLASSPATH,
2059:                                            Messages
2060:                                                    .bind(
2061:                                                            Messages.classpath_unboundSourceAttachment,
2062:                                                            new String[] {
2063:                                                                    sourceAttachment
2064:                                                                            .toString(),
2065:                                                                    path
2066:                                                                            .toString(),
2067:                                                                    projectName }));
2068:                                }
2069:                            }
2070:                        } else if (target instanceof  File) {
2071:                            File file = JavaModel.getFile(target);
2072:                            if (file == null) {
2073:                                return new JavaModelStatus(
2074:                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
2075:                                        Messages
2076:                                                .bind(
2077:                                                        Messages.classpath_illegalExternalFolder,
2078:                                                        new String[] {
2079:                                                                path
2080:                                                                        .toOSString(),
2081:                                                                projectName }));
2082:                            } else if (!org.eclipse.jdt.internal.compiler.util.Util
2083:                                    .isArchiveFileName(file.getName())) {
2084:                                return new JavaModelStatus(
2085:                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
2086:                                        Messages
2087:                                                .bind(
2088:                                                        Messages.classpath_illegalLibraryArchive,
2089:                                                        (new String[] {
2090:                                                                path
2091:                                                                        .toOSString(),
2092:                                                                projectName })));
2093:                            } else if (checkSourceAttachment
2094:                                    && sourceAttachment != null
2095:                                    && !sourceAttachment.isEmpty()
2096:                                    && JavaModel.getTarget(workspaceRoot,
2097:                                            sourceAttachment, true) == null) {
2098:                                return new JavaModelStatus(
2099:                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
2100:                                        Messages
2101:                                                .bind(
2102:                                                        Messages.classpath_unboundSourceAttachment,
2103:                                                        new String[] {
2104:                                                                sourceAttachment
2105:                                                                        .toString(),
2106:                                                                path
2107:                                                                        .toOSString(),
2108:                                                                projectName }));
2109:                            }
2110:                        } else {
2111:                            boolean isExternal = path.getDevice() != null
2112:                                    || !workspaceRoot.getProject(
2113:                                            path.segment(0)).exists();
2114:                            if (isExternal) {
2115:                                return new JavaModelStatus(
2116:                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
2117:                                        Messages
2118:                                                .bind(
2119:                                                        Messages.classpath_unboundLibrary,
2120:                                                        new String[] {
2121:                                                                path
2122:                                                                        .toOSString(),
2123:                                                                projectName }));
2124:                            } else {
2125:                                return new JavaModelStatus(
2126:                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
2127:                                        Messages
2128:                                                .bind(
2129:                                                        Messages.classpath_unboundLibrary,
2130:                                                        new String[] {
2131:                                                                entryPathMsg,
2132:                                                                projectName }));
2133:                            }
2134:                        }
2135:                    } else {
2136:                        return new JavaModelStatus(
2137:                                IJavaModelStatusConstants.INVALID_CLASSPATH,
2138:                                Messages.bind(
2139:                                        Messages.classpath_illegalLibraryPath,
2140:                                        new String[] { entryPathMsg,
2141:                                                projectName }));
2142:                    }
2143:                    break;
2144:
2145:                // project entry check
2146:                case IClasspathEntry.CPE_PROJECT:
2147:                    if (path.isAbsolute() && path.segmentCount() == 1) {
2148:                        IProject prereqProjectRsc = workspaceRoot
2149:                                .getProject(path.segment(0));
2150:                        IJavaProject prereqProject = JavaCore
2151:                                .create(prereqProjectRsc);
2152:                        try {
2153:                            if (!prereqProjectRsc.exists()
2154:                                    || !prereqProjectRsc
2155:                                            .hasNature(JavaCore.NATURE_ID)) {
2156:                                return new JavaModelStatus(
2157:                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
2158:                                        Messages
2159:                                                .bind(
2160:                                                        Messages.classpath_unboundProject,
2161:                                                        new String[] {
2162:                                                                path.segment(0),
2163:                                                                projectName }));
2164:                            }
2165:                            if (!prereqProjectRsc.isOpen()) {
2166:                                return new JavaModelStatus(
2167:                                        IJavaModelStatusConstants.INVALID_CLASSPATH,
2168:                                        Messages
2169:                                                .bind(
2170:                                                        Messages.classpath_closedProject,
2171:                                                        new String[] { path
2172:                                                                .segment(0) }));
2173:                            }
2174:                            if (!JavaCore.IGNORE
2175:                                    .equals(project
2176:                                            .getOption(
2177:                                                    JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL,
2178:                                                    true))) {
2179:                                long projectTargetJDK = CompilerOptions
2180:                                        .versionToJdkLevel(project
2181:                                                .getOption(
2182:                                                        JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
2183:                                                        true));
2184:                                long prereqProjectTargetJDK = CompilerOptions
2185:                                        .versionToJdkLevel(prereqProject
2186:                                                .getOption(
2187:                                                        JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
2188:                                                        true));
2189:                                if (prereqProjectTargetJDK > projectTargetJDK) {
2190:                                    return new JavaModelStatus(
2191:                                            IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL,
2192:                                            project,
2193:                                            path,
2194:                                            CompilerOptions
2195:                                                    .versionFromJdkLevel(prereqProjectTargetJDK));
2196:                                }
2197:                            }
2198:                        } catch (CoreException e) {
2199:                            return new JavaModelStatus(
2200:                                    IJavaModelStatusConstants.INVALID_CLASSPATH,
2201:                                    Messages.bind(
2202:                                            Messages.classpath_unboundProject,
2203:                                            new String[] { path.segment(0),
2204:                                                    projectName }));
2205:                        }
2206:                    } else {
2207:                        return new JavaModelStatus(
2208:                                IJavaModelStatusConstants.INVALID_CLASSPATH,
2209:                                Messages.bind(
2210:                                        Messages.classpath_illegalProjectPath,
2211:                                        new String[] { path.toString(),
2212:                                                projectName }));
2213:                    }
2214:                    break;
2215:
2216:                // project source folder
2217:                case IClasspathEntry.CPE_SOURCE:
2218:                    if (((entry.getInclusionPatterns() != null && entry
2219:                            .getInclusionPatterns().length > 0) || (entry
2220:                            .getExclusionPatterns() != null && entry
2221:                            .getExclusionPatterns().length > 0))
2222:                            && JavaCore.DISABLED
2223:                                    .equals(project
2224:                                            .getOption(
2225:                                                    JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS,
2226:                                                    true))) {
2227:                        return new JavaModelStatus(
2228:                                IJavaModelStatusConstants.DISABLED_CP_EXCLUSION_PATTERNS,
2229:                                project, path);
2230:                    }
2231:                    if (entry.getOutputLocation() != null
2232:                            && JavaCore.DISABLED
2233:                                    .equals(project
2234:                                            .getOption(
2235:                                                    JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS,
2236:                                                    true))) {
2237:                        return new JavaModelStatus(
2238:                                IJavaModelStatusConstants.DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS,
2239:                                project, path);
2240:                    }
2241:                    if (path.isAbsolute() && !path.isEmpty()) {
2242:                        IPath projectPath = project.getProject().getFullPath();
2243:                        if (!projectPath.isPrefixOf(path)
2244:                                || JavaModel.getTarget(workspaceRoot, path,
2245:                                        true) == null) {
2246:                            return new JavaModelStatus(
2247:                                    IJavaModelStatusConstants.INVALID_CLASSPATH,
2248:                                    Messages
2249:                                            .bind(
2250:                                                    Messages.classpath_unboundSourceFolder,
2251:                                                    new String[] {
2252:                                                            entryPathMsg,
2253:                                                            projectName }));
2254:                        }
2255:                    } else {
2256:                        return new JavaModelStatus(
2257:                                IJavaModelStatusConstants.INVALID_CLASSPATH,
2258:                                Messages
2259:                                        .bind(
2260:                                                Messages.classpath_illegalSourceFolderPath,
2261:                                                new String[] { entryPathMsg,
2262:                                                        projectName }));
2263:                    }
2264:                    break;
2265:                }
2266:
2267:                // Validate extra attributes
2268:                IClasspathAttribute[] extraAttributes = entry
2269:                        .getExtraAttributes();
2270:                if (extraAttributes != null) {
2271:                    int length = extraAttributes.length;
2272:                    HashSet set = new HashSet(length);
2273:                    for (int i = 0; i < length; i++) {
2274:                        String attName = extraAttributes[i].getName();
2275:                        if (!set.add(attName)) {
2276:                            return new JavaModelStatus(
2277:                                    IJavaModelStatusConstants.NAME_COLLISION,
2278:                                    Messages
2279:                                            .bind(
2280:                                                    Messages.classpath_duplicateEntryExtraAttribute,
2281:                                                    new String[] { attName,
2282:                                                            entryPathMsg,
2283:                                                            projectName }));
2284:                        }
2285:                    }
2286:                }
2287:
2288:                return JavaModelStatus.VERIFIED_OK;
2289:            }
2290:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.