<s> package org . eclipse . jdt . internal . core ; import java . io . ByteArrayOutputStream ; import java . io . File ; import java . io . IOException ; import java . io . InputStream ; import java . io . OutputStreamWriter ; import java . io . UnsupportedEncodingException ; import java . util . ArrayList ; import java . util . HashMap ; import java . util . HashSet ; import java . util . Iterator ; import java . util . List ; import java . util . Map ; import java . util . zip . ZipEntry ; import java . util . zip . ZipFile ; import org . eclipse . core . resources . IContainer ; import org . eclipse . core . resources . IFile ; import org . eclipse . core . resources . IProject ; import org . eclipse . core . resources . IResource ; import org . eclipse . core . resources . IWorkspaceRoot ; import org . eclipse . core . resources . ResourcesPlugin ; import org . eclipse . core . runtime . CoreException ; import org . eclipse . core . runtime . IPath ; import org . eclipse . core . runtime . IStatus ; import org . eclipse . core . runtime . Path ; import org . eclipse . jdt . core . IAccessRule ; import org . eclipse . jdt . core . IClasspathAttribute ; import org . eclipse . jdt . core . IClasspathContainer ; import org . eclipse . jdt . core . IClasspathEntry ; import org . eclipse . jdt . core . IJavaModelStatus ; import org . eclipse . jdt . core . IJavaModelStatusConstants ; import org . eclipse . jdt . core . IJavaProject ; import org . eclipse . jdt . core . IPackageFragmentRoot ; import org . eclipse . jdt . core . JavaCore ; import org . eclipse . jdt . core . JavaModelException ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . core . compiler . IProblem ; import org . eclipse . jdt . internal . compiler . env . AccessRestriction ; import org . eclipse . jdt . internal . compiler . env . AccessRule ; import org . eclipse . jdt . internal . compiler . env . AccessRuleSet ; import org . eclipse . jdt . internal . compiler . impl . CompilerOptions ; import org . eclipse . jdt . internal . compiler . util . ManifestAnalyzer ; import org . eclipse . jdt . internal . core . util . Messages ; import org . eclipse . jdt . internal . core . util . Util ; import org . w3c . dom . DOMException ; import org . w3c . dom . Element ; import org . w3c . dom . NamedNodeMap ; import org . w3c . dom . Node ; import org . w3c . dom . NodeList ; import org . w3c . dom . Text ; public class ClasspathEntry implements IClasspathEntry { public static class AssertionFailedException extends RuntimeException { private static final long serialVersionUID = - 171699380721189572L ; public AssertionFailedException ( String message ) { super ( message ) ; } } public static final String TAG_CLASSPATH = "classpath" ; public static final String TAG_CLASSPATHENTRY = "" ; public static final String TAG_REFERENCED_ENTRY = "" ; public static final String TAG_OUTPUT = "output" ; public static final String TAG_KIND = "kind" ; public static final String TAG_PATH = "path" ; public static final String TAG_SOURCEPATH = "sourcepath" ; public static final String TAG_ROOTPATH = "rootpath" ; public static final String TAG_EXPORTED = "exported" ; public static final String TAG_INCLUDING = "including" ; public static final String TAG_EXCLUDING = "excluding" ; public static final String TAG_ATTRIBUTES = "attributes" ; public static final String TAG_ATTRIBUTE = "attribute" ; public static final String TAG_ATTRIBUTE_NAME = "name" ; public static final String TAG_ATTRIBUTE_VALUE = "value" ; public static final String TAG_COMBINE_ACCESS_RULES = "" ; public static final String TAG_ACCESS_RULES = "accessrules" ; public static final String TAG_ACCESS_RULE = "accessrule" ; public static final String TAG_PATTERN = "pattern" ; public static final String TAG_ACCESSIBLE = "accessible" ; public static final String TAG_NON_ACCESSIBLE = "" ; public static final String TAG_DISCOURAGED = "discouraged" ; public static final String TAG_IGNORE_IF_BETTER = "" ; public int entryKind ; public int contentKind ; public IPath path ; private IPath [ ] inclusionPatterns ; private char [ ] [ ] fullInclusionPatternChars ; private IPath [ ] exclusionPatterns ; private char [ ] [ ] fullExclusionPatternChars ; private final static char [ ] [ ] UNINIT_PATTERNS = new char [ ] [ ] { "" . toCharArray ( ) } ; public final static ClasspathEntry [ ] NO_ENTRIES = new ClasspathEntry [ 0 ] ; private final static IPath [ ] NO_PATHS = new IPath [ 0 ] ; private final static IWorkspaceRoot workspaceRoot = ResourcesPlugin . getWorkspace ( ) . getRoot ( ) ; private boolean combineAccessRules ; private String rootID ; private AccessRuleSet accessRuleSet ; static class UnknownXmlElements { String [ ] attributes ; ArrayList children ; } public final static IPath [ ] INCLUDE_ALL = { } ; public final static IPath [ ] EXCLUDE_NONE = { } ; public final static IClasspathAttribute [ ] NO_EXTRA_ATTRIBUTES = { } ; public final static IAccessRule [ ] NO_ACCESS_RULES = { } ; public IPath sourceAttachmentPath ; public IPath sourceAttachmentRootPath ; public IClasspathEntry referencingEntry ; public IPath specificOutputLocation ; public static final int K_OUTPUT = 10 ; public static final String DOT_DOT = ".." ; public boolean isExported ; public IClasspathAttribute [ ] extraAttributes ; public ClasspathEntry ( int contentKind , int entryKind , IPath path , IPath [ ] inclusionPatterns , IPath [ ] exclusionPatterns , IPath sourceAttachmentPath , IPath sourceAttachmentRootPath , IPath specificOutputLocation , boolean isExported , IAccessRule [ ] accessRules , boolean combineAccessRules , IClasspathAttribute [ ] extraAttributes ) { this ( contentKind , entryKind , path , inclusionPatterns , exclusionPatterns , sourceAttachmentPath , sourceAttachmentRootPath , specificOutputLocation , null , isExported , accessRules , combineAccessRules , extraAttributes ) ; } public ClasspathEntry ( int contentKind , int entryKind , IPath path , IPath [ ] inclusionPatterns , IPath [ ] exclusionPatterns , IPath sourceAttachmentPath , IPath sourceAttachmentRootPath , IPath specificOutputLocation , IClasspathEntry referencingEntry , boolean isExported , IAccessRule [ ] accessRules , boolean combineAccessRules , IClasspathAttribute [ ] extraAttributes ) { this . contentKind = contentKind ; this . entryKind = entryKind ; this . path = path ; this . inclusionPatterns = inclusionPatterns ; this . exclusionPatterns = exclusionPatterns ; this . referencingEntry = referencingEntry ; int length ; if ( accessRules != null && ( length = accessRules . length ) > 0 ) { AccessRule [ ] rules = new AccessRule [ length ] ; System . arraycopy ( accessRules , 0 , rules , 0 , length ) ; byte classpathEntryType ; String classpathEntryName ; JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; if ( this . entryKind == CPE_PROJECT || this . entryKind == CPE_SOURCE ) { classpathEntryType = AccessRestriction . PROJECT ; classpathEntryName = manager . intern ( getPath ( ) . segment ( 0 ) ) ; } else { classpathEntryType = AccessRestriction . LIBRARY ; Object target = JavaModel . getWorkspaceTarget ( path ) ; if ( target == null ) { classpathEntryName = manager . intern ( path . toOSString ( ) ) ; } else { classpathEntryName = manager . intern ( path . makeRelative ( ) . toString ( ) ) ; } } this . accessRuleSet = new AccessRuleSet ( rules , classpathEntryType , classpathEntryName ) ; } this . combineAccessRules = combineAccessRules ; this . extraAttributes = extraAttributes ; if ( inclusionPatterns != INCLUDE_ALL && inclusionPatterns . length > 0 ) { this . fullInclusionPatternChars = UNINIT_PATTERNS ; } if ( exclusionPatterns . length > 0 ) { this . fullExclusionPatternChars = UNINIT_PATTERNS ; } this . sourceAttachmentPath = sourceAttachmentPath ; this . sourceAttachmentRootPath = sourceAttachmentRootPath ; this . specificOutputLocation = specificOutputLocation ; this . isExported = isExported ; } public boolean combineAccessRules ( ) { return this . combineAccessRules ; } public ClasspathEntry combineWith ( ClasspathEntry referringEntry ) { if ( referringEntry == null ) return this ; if ( referringEntry . isExported ( ) || referringEntry . getAccessRuleSet ( ) != null ) { boolean combine = this . entryKind == CPE_SOURCE || referringEntry . combineAccessRules ( ) ; return new ClasspathEntry ( getContentKind ( ) , getEntryKind ( ) , getPath ( ) , this . inclusionPatterns , this . exclusionPatterns , getSourceAttachmentPath ( ) , getSourceAttachmentRootPath ( ) , getOutputLocation ( ) , referringEntry . isExported ( ) || this . isExported , combine ( referringEntry . getAccessRules ( ) , getAccessRules ( ) , combine ) , this . combineAccessRules , this . extraAttributes ) ; } return this ; } private IAccessRule [ ] combine ( IAccessRule [ ] referringRules , IAccessRule [ ] rules , boolean combine ) { if ( ! combine ) return rules ; if ( rules == null || rules . length == 0 ) return referringRules ; int referringRulesLength = referringRules . length ; int accessRulesLength = rules . length ; int rulesLength = referringRulesLength + accessRulesLength ; IAccessRule [ ] result = new IAccessRule [ rulesLength ] ; System . arraycopy ( referringRules , 0 , result , 0 , referringRulesLength ) ; System . arraycopy ( rules , 0 , result , referringRulesLength , accessRulesLength ) ; return result ; } static IClasspathAttribute [ ] decodeExtraAttributes ( NodeList attributes ) { if ( attributes == null ) return NO_EXTRA_ATTRIBUTES ; int length = attributes . getLength ( ) ; if ( length == 0 ) return NO_EXTRA_ATTRIBUTES ; IClasspathAttribute [ ] result = new IClasspathAttribute [ length ] ; int index = 0 ; for ( int i = 0 ; i < length ; ++ i ) { Node node = attributes . item ( i ) ; if ( node . getNodeType ( ) == Node . ELEMENT_NODE ) { Element attribute = ( Element ) node ; String name = attribute . getAttribute ( TAG_ATTRIBUTE_NAME ) ; if ( name == null ) continue ; String value = attribute . getAttribute ( TAG_ATTRIBUTE_VALUE ) ; if ( value == null ) continue ; result [ index ++ ] = new ClasspathAttribute ( name , value ) ; } } if ( index != length ) System . arraycopy ( result , 0 , result = new IClasspathAttribute [ index ] , 0 , index ) ; return result ; } static IAccessRule [ ] decodeAccessRules ( NodeList list ) { if ( list == null ) return null ; int length = list . getLength ( ) ; if ( length == 0 ) return null ; IAccessRule [ ] result = new IAccessRule [ length ] ; int index = 0 ; for ( int i = 0 ; i < length ; i ++ ) { Node accessRule = list . item ( i ) ; if ( accessRule . getNodeType ( ) == Node . ELEMENT_NODE ) { Element elementAccessRule = ( Element ) accessRule ; String pattern = elementAccessRule . getAttribute ( TAG_PATTERN ) ; if ( pattern == null ) continue ; String tagKind = elementAccessRule . getAttribute ( TAG_KIND ) ; int kind ; if ( TAG_ACCESSIBLE . equals ( tagKind ) ) kind = IAccessRule . K_ACCESSIBLE ; else if ( TAG_NON_ACCESSIBLE . equals ( tagKind ) ) kind = IAccessRule . K_NON_ACCESSIBLE ; else if ( TAG_DISCOURAGED . equals ( tagKind ) ) kind = IAccessRule . K_DISCOURAGED ; else continue ; boolean ignoreIfBetter = "true" . equals ( elementAccessRule . getAttribute ( TAG_IGNORE_IF_BETTER ) ) ; result [ index ++ ] = new ClasspathAccessRule ( new Path ( pattern ) , ignoreIfBetter ? kind | IAccessRule . IGNORE_IF_BETTER : kind ) ; } } if ( index != length ) System . arraycopy ( result , 0 , result = new IAccessRule [ index ] , 0 , index ) ; return result ; } private static IPath [ ] decodePatterns ( NamedNodeMap nodeMap , String tag ) { String sequence = removeAttribute ( tag , nodeMap ) ; if ( ! sequence . equals ( "" ) ) { char [ ] [ ] patterns = CharOperation . splitOn ( '|' , sequence . toCharArray ( ) ) ; int patternCount ; if ( ( patternCount = patterns . length ) > 0 ) { IPath [ ] paths = new IPath [ patternCount ] ; int index = 0 ; for ( int j = 0 ; j < patternCount ; j ++ ) { char [ ] pattern = patterns [ j ] ; if ( pattern . length == 0 ) continue ; paths [ index ++ ] = new Path ( new String ( pattern ) ) ; } if ( index < patternCount ) System . arraycopy ( paths , 0 , paths = new IPath [ index ] , 0 , index ) ; return paths ; } } return null ; } private static void decodeUnknownNode ( Node node , StringBuffer buffer , IJavaProject project ) { ByteArrayOutputStream s = new ByteArrayOutputStream ( ) ; OutputStreamWriter writer ; try { writer = new OutputStreamWriter ( s , "UTF8" ) ; XMLWriter xmlWriter = new XMLWriter ( writer , project , false ) ; decodeUnknownNode ( node , xmlWriter , true ) ; xmlWriter . flush ( ) ; xmlWriter . close ( ) ; buffer . append ( s . toString ( "UTF8" ) ) ; } catch ( UnsupportedEncodingException e ) { } } private static void decodeUnknownNode ( Node node , XMLWriter xmlWriter , boolean insertNewLine ) { switch ( node . getNodeType ( ) ) { case Node . ELEMENT_NODE : NamedNodeMap attributes ; HashMap parameters = null ; if ( ( attributes = node . getAttributes ( ) ) != null ) { int length = attributes . getLength ( ) ; if ( length > 0 ) { parameters = new HashMap ( ) ; for ( int i = 0 ; i < length ; i ++ ) { Node attribute = attributes . item ( i ) ; parameters . put ( attribute . getNodeName ( ) , attribute . getNodeValue ( ) ) ; } } } NodeList children = node . getChildNodes ( ) ; int childrenLength = children . getLength ( ) ; String nodeName = node . getNodeName ( ) ; xmlWriter . printTag ( nodeName , parameters , false , false , childrenLength == 0 ) ; if ( childrenLength > 0 ) { for ( int i = 0 ; i < childrenLength ; i ++ ) { decodeUnknownNode ( children . item ( i ) , xmlWriter , false ) ; } xmlWriter . endTag ( nodeName , false , insertNewLine ) ; } break ; case Node . TEXT_NODE : String data = ( ( Text ) node ) . getData ( ) ; xmlWriter . printString ( data , false , false ) ; break ; } } public char [ ] [ ] fullExclusionPatternChars ( ) { if ( this . fullExclusionPatternChars == UNINIT_PATTERNS ) { int length = this . exclusionPatterns . length ; this . fullExclusionPatternChars = new char [ length ] [ ] ; IPath prefixPath = this . path . removeTrailingSeparator ( ) ; for ( int i = 0 ; i < length ; i ++ ) { this . fullExclusionPatternChars [ i ] = prefixPath . append ( this . exclusionPatterns [ i ] ) . toString ( ) . toCharArray ( ) ; } } return this . fullExclusionPatternChars ; } public char [ ] [ ] fullInclusionPatternChars ( ) { if ( this . fullInclusionPatternChars == UNINIT_PATTERNS ) { int length = this . inclusionPatterns . length ; this . fullInclusionPatternChars = new char [ length ] [ ] ; IPath prefixPath = this . path . removeTrailingSeparator ( ) ; for ( int i = 0 ; i < length ; i ++ ) { this . fullInclusionPatternChars [ i ] = prefixPath . append ( this . inclusionPatterns [ i ] ) . toString ( ) . toCharArray ( ) ; } } return this . fullInclusionPatternChars ; } public void elementEncode ( XMLWriter writer , IPath projectPath , boolean indent , boolean newLine , Map unknownElements , boolean isReferencedEntry ) { HashMap parameters = new HashMap ( ) ; parameters . put ( TAG_KIND , ClasspathEntry . kindToString ( this . entryKind ) ) ; IPath xmlPath = this . path ; if ( this . entryKind != IClasspathEntry . CPE_VARIABLE && this . entryKind != IClasspathEntry . CPE_CONTAINER ) { if ( xmlPath . isAbsolute ( ) ) { if ( projectPath != null && projectPath . isPrefixOf ( xmlPath ) ) { if ( xmlPath . segment ( 0 ) . equals ( projectPath . segment ( 0 ) ) ) { xmlPath = xmlPath . removeFirstSegments ( 1 ) ; xmlPath = xmlPath . makeRelative ( ) ; } else { xmlPath = xmlPath . makeAbsolute ( ) ; } } } } parameters . put ( TAG_PATH , String . valueOf ( xmlPath ) ) ; if ( this . sourceAttachmentPath != null ) { xmlPath = this . sourceAttachmentPath ; if ( this . entryKind != IClasspathEntry . CPE_VARIABLE && projectPath != null && projectPath . isPrefixOf ( xmlPath ) ) { if ( xmlPath . segment ( 0 ) . equals ( projectPath . segment ( 0 ) ) ) { xmlPath = xmlPath . removeFirstSegments ( 1 ) ; xmlPath = xmlPath . makeRelative ( ) ; } } parameters . put ( TAG_SOURCEPATH , String . valueOf ( xmlPath ) ) ; } if ( this . sourceAttachmentRootPath != null ) { parameters . put ( TAG_ROOTPATH , String . valueOf ( this . sourceAttachmentRootPath ) ) ; } if ( this . isExported ) { parameters . put ( TAG_EXPORTED , "true" ) ; } encodePatterns ( this . inclusionPatterns , TAG_INCLUDING , parameters ) ; encodePatterns ( this . exclusionPatterns , TAG_EXCLUDING , parameters ) ; if ( this . entryKind == CPE_PROJECT && ! this . combineAccessRules ) parameters . put ( TAG_COMBINE_ACCESS_RULES , "false" ) ; UnknownXmlElements unknownXmlElements = unknownElements == null ? null : ( UnknownXmlElements ) unknownElements . get ( this . path ) ; String [ ] unknownAttributes ; if ( unknownXmlElements != null && ( unknownAttributes = unknownXmlElements . attributes ) != null ) for ( int i = 0 , length = unknownAttributes . length ; i < length ; i += 2 ) { String tagName = unknownAttributes [ i ] ; String tagValue = unknownAttributes [ i + 1 ] ; parameters . put ( tagName , tagValue ) ; } if ( this . specificOutputLocation != null ) { IPath outputLocation = this . specificOutputLocation . removeFirstSegments ( 1 ) ; outputLocation = outputLocation . makeRelative ( ) ; parameters . put ( TAG_OUTPUT , String . valueOf ( outputLocation ) ) ; } boolean hasExtraAttributes = this . extraAttributes . length != 0 ; boolean hasRestrictions = getAccessRuleSet ( ) != null ; ArrayList unknownChildren = unknownXmlElements != null ? unknownXmlElements . children : null ; boolean hasUnknownChildren = unknownChildren != null ; String tagName = isReferencedEntry ? TAG_REFERENCED_ENTRY : TAG_CLASSPATHENTRY ; writer . printTag ( tagName , parameters , indent , newLine , ! hasExtraAttributes && ! hasRestrictions && ! hasUnknownChildren ) ; if ( hasExtraAttributes ) encodeExtraAttributes ( writer , indent , newLine ) ; if ( hasRestrictions ) encodeAccessRules ( writer , indent , newLine ) ; if ( hasUnknownChildren ) encodeUnknownChildren ( writer , indent , newLine , unknownChildren ) ; if ( hasExtraAttributes || hasRestrictions || hasUnknownChildren ) writer . endTag ( tagName , indent , true ) ; } void encodeExtraAttributes ( XMLWriter writer , boolean indent , boolean newLine ) { writer . startTag ( TAG_ATTRIBUTES , indent ) ; for ( int i = 0 ; i < this . extraAttributes . length ; i ++ ) { IClasspathAttribute attribute = this . extraAttributes [ i ] ; HashMap parameters = new HashMap ( ) ; parameters . put ( TAG_ATTRIBUTE_NAME , attribute . getName ( ) ) ; parameters . put ( TAG_ATTRIBUTE_VALUE , attribute . getValue ( ) ) ; writer . printTag ( TAG_ATTRIBUTE , parameters , indent , newLine , true ) ; } writer . endTag ( TAG_ATTRIBUTES , indent , true ) ; } void encodeAccessRules ( XMLWriter writer , boolean indent , boolean newLine ) { writer . startTag ( TAG_ACCESS_RULES , indent ) ; AccessRule [ ] rules = getAccessRuleSet ( ) . getAccessRules ( ) ; for ( int i = 0 , length = rules . length ; i < length ; i ++ ) { encodeAccessRule ( rules [ i ] , writer , indent , newLine ) ; } writer . endTag ( TAG_ACCESS_RULES , indent , true ) ; } private void encodeAccessRule ( AccessRule accessRule , XMLWriter writer , boolean indent , boolean newLine ) { HashMap parameters = new HashMap ( ) ; parameters . put ( TAG_PATTERN , new String ( accessRule . pattern ) ) ; switch ( accessRule . getProblemId ( ) ) { case IProblem . ForbiddenReference : parameters . put ( TAG_KIND , TAG_NON_ACCESSIBLE ) ; break ; case IProblem . DiscouragedReference : parameters . put ( TAG_KIND , TAG_DISCOURAGED ) ; break ; default : parameters . put ( TAG_KIND , TAG_ACCESSIBLE ) ; break ; } if ( accessRule . ignoreIfBetter ( ) ) parameters . put ( TAG_IGNORE_IF_BETTER , "true" ) ; writer . printTag ( TAG_ACCESS_RULE , parameters , indent , newLine , true ) ; } private void encodeUnknownChildren ( XMLWriter writer , boolean indent , boolean newLine , ArrayList unknownChildren ) { for ( int i = 0 , length = unknownChildren . size ( ) ; i < length ; i ++ ) { String child = ( String ) unknownChildren . get ( i ) ; writer . printString ( child , indent , false ) ; } } public static IClasspathEntry elementDecode ( Element element , IJavaProject project , Map unknownElements ) { IPath projectPath = project . getProject ( ) . getFullPath ( ) ; NamedNodeMap attributes = element . getAttributes ( ) ; NodeList children = element . getChildNodes ( ) ; boolean [ ] foundChildren = new boolean [ children . getLength ( ) ] ; String kindAttr = removeAttribute ( TAG_KIND , attributes ) ; String pathAttr = removeAttribute ( TAG_PATH , attributes ) ; IPath path = new Path ( pathAttr ) ; int kind = kindFromString ( kindAttr ) ; if ( kind != IClasspathEntry . CPE_VARIABLE && kind != IClasspathEntry . CPE_CONTAINER && ! path . isAbsolute ( ) ) { if ( ! ( path . segmentCount ( ) > 0 && path . segment ( 0 ) . equals ( ClasspathEntry . DOT_DOT ) ) ) { path = projectPath . append ( path ) ; } } IPath sourceAttachmentPath = element . hasAttribute ( TAG_SOURCEPATH ) ? new Path ( removeAttribute ( TAG_SOURCEPATH , attributes ) ) : null ; if ( kind != IClasspathEntry . CPE_VARIABLE && sourceAttachmentPath != null && ! sourceAttachmentPath . isAbsolute ( ) ) { sourceAttachmentPath = projectPath . append ( sourceAttachmentPath ) ; } IPath sourceAttachmentRootPath = element . hasAttribute ( TAG_ROOTPATH ) ? new Path ( removeAttribute ( TAG_ROOTPATH , attributes ) ) : null ; boolean isExported = removeAttribute ( TAG_EXPORTED , attributes ) . equals ( "true" ) ; IPath [ ] inclusionPatterns = decodePatterns ( attributes , TAG_INCLUDING ) ; if ( inclusionPatterns == null ) inclusionPatterns = INCLUDE_ALL ; IPath [ ] exclusionPatterns = decodePatterns ( attributes , TAG_EXCLUDING ) ; if ( exclusionPatterns == null ) exclusionPatterns = EXCLUDE_NONE ; NodeList attributeList = getChildAttributes ( TAG_ACCESS_RULES , children , foundChildren ) ; IAccessRule [ ] accessRules = decodeAccessRules ( attributeList ) ; if ( accessRules == null ) { accessRules = getAccessRules ( inclusionPatterns , exclusionPatterns ) ; } boolean combineAccessRestrictions = ! removeAttribute ( TAG_COMBINE_ACCESS_RULES , attributes ) . equals ( "false" ) ; attributeList = getChildAttributes ( TAG_ATTRIBUTES , children , foundChildren ) ; IClasspathAttribute [ ] extraAttributes = decodeExtraAttributes ( attributeList ) ; IPath outputLocation = element . hasAttribute ( TAG_OUTPUT ) ? projectPath . append ( removeAttribute ( TAG_OUTPUT , attributes ) ) : null ; String [ ] unknownAttributes = null ; ArrayList unknownChildren = null ; if ( unknownElements != null ) { int unknownAttributeLength = attributes . getLength ( ) ; if ( unknownAttributeLength != 0 ) { unknownAttributes = new String [ unknownAttributeLength * 2 ] ; for ( int i = 0 ; i < unknownAttributeLength ; i ++ ) { Node attribute = attributes . item ( i ) ; unknownAttributes [ i * 2 ] = attribute . getNodeName ( ) ; unknownAttributes [ i * 2 + 1 ] = attribute . getNodeValue ( ) ; } } for ( int i = 0 , length = foundChildren . length ; i < length ; i ++ ) { if ( ! foundChildren [ i ] ) { Node node = children . item ( i ) ; if ( node . getNodeType ( ) != Node . ELEMENT_NODE ) continue ; if ( unknownChildren == null ) unknownChildren = new ArrayList ( ) ; StringBuffer buffer = new StringBuffer ( ) ; decodeUnknownNode ( node , buffer , project ) ; unknownChildren . add ( buffer . toString ( ) ) ; } } } IClasspathEntry entry = null ; switch ( kind ) { case IClasspathEntry . CPE_PROJECT : entry = new ClasspathEntry ( IPackageFragmentRoot . K_SOURCE , IClasspathEntry . CPE_PROJECT , path , ClasspathEntry . INCLUDE_ALL , ClasspathEntry . EXCLUDE_NONE , null , null , null , isExported , accessRules , combineAccessRestrictions , extraAttributes ) ; break ; case IClasspathEntry . CPE_LIBRARY : entry = JavaCore . newLibraryEntry ( path , sourceAttachmentPath , sourceAttachmentRootPath , accessRules , extraAttributes , isExported ) ; break ; case IClasspathEntry . CPE_SOURCE : String projSegment = path . segment ( 0 ) ; if ( projSegment != null && projSegment . equals ( project . getElementName ( ) ) ) { entry = JavaCore . newSourceEntry ( path , inclusionPatterns , exclusionPatterns , outputLocation , extraAttributes ) ; } else { if ( path . segmentCount ( ) == 1 ) { entry = JavaCore . newProjectEntry ( path , accessRules , combineAccessRestrictions , extraAttributes , isExported ) ; } else { entry = JavaCore . newSourceEntry ( path , inclusionPatterns , exclusionPatterns , outputLocation , extraAttributes ) ; } } break ; case IClasspathEntry . CPE_VARIABLE : entry = JavaCore . newVariableEntry ( path , sourceAttachmentPath , sourceAttachmentRootPath , accessRules , extraAttributes , isExported ) ; break ; case IClasspathEntry . CPE_CONTAINER : entry = JavaCore . newContainerEntry ( path , accessRules , extraAttributes , isExported ) ; break ; case ClasspathEntry . K_OUTPUT : if ( ! path . isAbsolute ( ) ) return null ; entry = new ClasspathEntry ( ClasspathEntry . K_OUTPUT , IClasspathEntry . CPE_LIBRARY , path , INCLUDE_ALL , EXCLUDE_NONE , null , null , null , false , null , false , NO_EXTRA_ATTRIBUTES ) ; break ; default : throw new AssertionFailedException ( Messages . bind ( Messages . classpath_unknownKind , kindAttr ) ) ; } if ( unknownAttributes != null || unknownChildren != null ) { UnknownXmlElements unknownXmlElements = new UnknownXmlElements ( ) ; unknownXmlElements . attributes = unknownAttributes ; unknownXmlElements . children = unknownChildren ; unknownElements . put ( path , unknownXmlElements ) ; } return entry ; } public static boolean hasDotDot ( IPath path ) { for ( int i = 0 , length = path . segmentCount ( ) ; i < length ; i ++ ) { if ( DOT_DOT . equals ( path . segment ( i ) ) ) return true ; } return false ; } public static NodeList getChildAttributes ( String childName , NodeList children , boolean [ ] foundChildren ) { for ( int i = 0 , length = foundChildren . length ; i < length ; i ++ ) { Node node = children . item ( i ) ; if ( childName . equals ( node . getNodeName ( ) ) ) { foundChildren [ i ] = true ; return node . getChildNodes ( ) ; } } return null ; } private static String removeAttribute ( String nodeName , NamedNodeMap nodeMap ) { Node node = removeNode ( nodeName , nodeMap ) ; if ( node == null ) return "" ; return node . getNodeValue ( ) ; } private static Node removeNode ( String nodeName , NamedNodeMap nodeMap ) { try { return nodeMap . removeNamedItem ( nodeName ) ; } catch ( DOMException e ) { if ( e . code != DOMException . NOT_FOUND_ERR ) throw e ; return null ; } } public static IPath [ ] resolvedChainedLibraries ( IPath jarPath ) { ArrayList result = new ArrayList ( ) ; resolvedChainedLibraries ( jarPath , new HashSet ( ) , result ) ; if ( result . size ( ) == 0 ) return NO_PATHS ; return ( IPath [ ] ) result . toArray ( new IPath [ result . size ( ) ] ) ; } private static void resolvedChainedLibraries ( IPath jarPath , HashSet visited , ArrayList result ) { if ( visited . contains ( jarPath ) ) return ; visited . add ( jarPath ) ; JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; if ( manager . isNonChainingJar ( jarPath ) ) return ; List calledFileNames = getCalledFileNames ( jarPath ) ; if ( calledFileNames == null ) { manager . addNonChainingJar ( jarPath ) ; } else { Iterator calledFilesIterator = calledFileNames . iterator ( ) ; IPath directoryPath = jarPath . removeLastSegments ( 1 ) ; while ( calledFilesIterator . hasNext ( ) ) { String calledFileName = ( String ) calledFilesIterator . next ( ) ; if ( ! directoryPath . isValidPath ( calledFileName ) ) { if ( JavaModelManager . CP_RESOLVE_VERBOSE_FAILURE ) { Util . verbose ( "" + calledFileName + "" + jarPath . toOSString ( ) ) ; } } else { IPath calledJar = directoryPath . append ( new Path ( calledFileName ) ) ; if ( calledJar . segmentCount ( ) == 0 ) { if ( JavaModelManager . CP_RESOLVE_VERBOSE_FAILURE ) { Util . verbose ( "" + calledFileName + "" + jarPath . toOSString ( ) ) ; } continue ; } resolvedChainedLibraries ( calledJar , visited , result ) ; result . add ( calledJar ) ; } } } } private static List getCalledFileNames ( IPath jarPath ) { Object target = JavaModel . getTarget ( jarPath , true ) ; if ( ! ( target instanceof IFile || target instanceof File ) ) return null ; JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; ZipFile zip = null ; InputStream inputStream = null ; List calledFileNames = null ; try { zip = manager . getZipFile ( jarPath ) ; ZipEntry manifest = zip . getEntry ( "" ) ; if ( manifest == null ) return null ; ManifestAnalyzer analyzer = new ManifestAnalyzer ( ) ; inputStream = zip . getInputStream ( manifest ) ; boolean success = analyzer . analyzeManifestContents ( inputStream ) ; calledFileNames = analyzer . getCalledFileNames ( ) ; if ( ! success || analyzer . getClasspathSectionsCount ( ) == 1 && calledFileNames == null ) { if ( JavaModelManager . CP_RESOLVE_VERBOSE_FAILURE ) { Util . verbose ( "" + jarPath . toOSString ( ) ) ; } return null ; } else if ( analyzer . getClasspathSectionsCount ( ) > 1 ) { if ( JavaModelManager . CP_RESOLVE_VERBOSE_FAILURE ) { Util . verbose ( "" + jarPath . toOSString ( ) ) ; } return null ; } } catch ( CoreException e ) { if ( JavaModelManager . CP_RESOLVE_VERBOSE_FAILURE ) { Util . verbose ( "" + jarPath . toOSString ( ) ) ; e . printStackTrace ( ) ; } } catch ( IOException e ) { if ( JavaModelManager . CP_RESOLVE_VERBOSE_FAILURE ) { Util . verbose ( "" + jarPath . toOSString ( ) ) ; e . printStackTrace ( ) ; } } finally { if ( inputStream != null ) { try { inputStream . close ( ) ; } catch ( IOException e ) { } } manager . closeZipFile ( zip ) ; } return calledFileNames ; } public static IPath resolveDotDot ( IPath path ) { IPath newPath = null ; IPath workspaceLocation = null ; for ( int i = 0 , length = path . segmentCount ( ) ; i < length ; i ++ ) { String segment = path . segment ( i ) ; if ( DOT_DOT . equals ( segment ) ) { if ( newPath == null ) { if ( i == 0 ) { workspaceLocation = workspaceRoot . getLocation ( ) ; newPath = workspaceLocation ; } else { newPath = path . removeFirstSegments ( i ) ; } } else { if ( newPath . segmentCount ( ) > 0 ) { newPath = newPath . removeLastSegments ( 1 ) ; } else { workspaceLocation = workspaceRoot . getLocation ( ) ; newPath = workspaceLocation ; } } } else if ( newPath != null ) { if ( newPath . equals ( workspaceLocation ) && workspaceRoot . getProject ( segment ) . isAccessible ( ) ) { newPath = new Path ( segment ) . makeAbsolute ( ) ; } else { newPath = newPath . append ( segment ) ; } } } if ( newPath == null ) return path ; return newPath ; } private static void encodePatterns ( IPath [ ] patterns , String tag , Map parameters ) { if ( patterns != null && patterns . length > 0 ) { StringBuffer rule = new StringBuffer ( 10 ) ; for ( int i = 0 , max = patterns . length ; i < max ; i ++ ) { if ( i > 0 ) rule . append ( '|' ) ; rule . append ( patterns [ i ] ) ; } parameters . put ( tag , String . valueOf ( rule ) ) ; } } public boolean equals ( Object object ) { if ( this == object ) return true ; if ( object instanceof ClasspathEntry ) { ClasspathEntry otherEntry = ( ClasspathEntry ) object ; if ( this . contentKind != otherEntry . getContentKind ( ) ) return false ; if ( this . entryKind != otherEntry . getEntryKind ( ) ) return false ; if ( this . isExported != otherEntry . isExported ( ) ) return false ; if ( ! this . path . equals ( otherEntry . getPath ( ) ) ) return false ; IPath otherPath = otherEntry . getSourceAttachmentPath ( ) ; if ( this . sourceAttachmentPath == null ) { if ( otherPath != null ) return false ; } else { if ( ! this . sourceAttachmentPath . equals ( otherPath ) ) return false ; } otherPath = otherEntry . getSourceAttachmentRootPath ( ) ; if ( this . sourceAttachmentRootPath == null ) { if ( otherPath != null ) return false ; } else { if ( ! this . sourceAttachmentRootPath . equals ( otherPath ) ) return false ; } if ( ! equalPatterns ( this . inclusionPatterns , otherEntry . getInclusionPatterns ( ) ) ) return false ; if ( ! equalPatterns ( this . exclusionPatterns , otherEntry . getExclusionPatterns ( ) ) ) return false ; AccessRuleSet otherRuleSet = otherEntry . getAccessRuleSet ( ) ; if ( getAccessRuleSet ( ) != null ) { if ( ! getAccessRuleSet ( ) . equals ( otherRuleSet ) ) return false ; } else if ( otherRuleSet != null ) return false ; if ( this . combineAccessRules != otherEntry . combineAccessRules ( ) ) return false ; otherPath = otherEntry . getOutputLocation ( ) ; if ( this . specificOutputLocation == null ) { if ( otherPath != null ) return false ; } else { if ( ! this . specificOutputLocation . equals ( otherPath ) ) return false ; } if ( ! equalAttributes ( this . extraAttributes , otherEntry . getExtraAttributes ( ) ) ) return false ; return true ; } else { return false ; } } private static boolean equalAttributes ( IClasspathAttribute [ ] firstAttributes , IClasspathAttribute [ ] secondAttributes ) { if ( firstAttributes != secondAttributes ) { if ( firstAttributes == null ) return false ; int length = firstAttributes . length ; if ( secondAttributes == null || secondAttributes . length != length ) return false ; for ( int i = 0 ; i < length ; i ++ ) { if ( ! firstAttributes [ i ] . equals ( secondAttributes [ i ] ) ) return false ; } } return true ; } private static boolean equalPatterns ( IPath [ ] firstPatterns , IPath [ ] secondPatterns ) { if ( firstPatterns != secondPatterns ) { if ( firstPatterns == null ) return false ; int length = firstPatterns . length ; if ( secondPatterns == null || secondPatterns . length != length ) return false ; for ( int i = 0 ; i < length ; i ++ ) { if ( ! firstPatterns [ i ] . toString ( ) . equals ( secondPatterns [ i ] . toString ( ) ) ) return false ; } } return true ; } public IAccessRule [ ] getAccessRules ( ) { if ( this . accessRuleSet == null ) return NO_ACCESS_RULES ; AccessRule [ ] rules = this . accessRuleSet . getAccessRules ( ) ; int length = rules . length ; if ( length == 0 ) return NO_ACCESS_RULES ; IAccessRule [ ] result = new IAccessRule [ length ] ; System . arraycopy ( rules , 0 , result , 0 , length ) ; return result ; } public AccessRuleSet getAccessRuleSet ( ) { return this . accessRuleSet ; } public int getContentKind ( ) { return this . contentKind ; } public int getEntryKind ( ) { return this . entryKind ; } public IPath [ ] getExclusionPatterns ( ) { return this . exclusionPatterns ; } public IClasspathAttribute [ ] getExtraAttributes ( ) { return this . extraAttributes ; } public IPath [ ] getInclusionPatterns ( ) { return this . inclusionPatterns ; } public IPath getOutputLocation ( ) { return this . specificOutputLocation ; } public IPath getPath ( ) { return this . path ; } public IPath getSourceAttachmentPath ( ) { return this . sourceAttachmentPath ; } public IPath getSourceAttachmentRootPath ( ) { return this . sourceAttachmentRootPath ; } public IClasspathEntry getReferencingEntry ( ) { return this . referencingEntry ; } public int hashCode ( ) { return this . path . hashCode ( ) ; } public boolean isExported ( ) { return this . isExported ; } public boolean isOptional ( ) { for ( int i = 0 , length = this . extraAttributes . length ; i < length ; i ++ ) { IClasspathAttribute attribute = this . extraAttributes [ i ] ; if ( IClasspathAttribute . OPTIONAL . equals ( attribute . getName ( ) ) && "true" . equals ( attribute . getValue ( ) ) ) return true ; } return false ; } static int kindFromString ( String kindStr ) { if ( kindStr . equalsIgnoreCase ( "prj" ) ) return IClasspathEntry . CPE_PROJECT ; if ( kindStr . equalsIgnoreCase ( "var" ) ) return IClasspathEntry . CPE_VARIABLE ; if ( kindStr . equalsIgnoreCase ( "con" ) ) return IClasspathEntry . CPE_CONTAINER ; if ( kindStr . equalsIgnoreCase ( "src" ) ) return IClasspathEntry . CPE_SOURCE ; if ( kindStr . equalsIgnoreCase ( "lib" ) ) return IClasspathEntry . CPE_LIBRARY ; if ( kindStr . equalsIgnoreCase ( "output" ) ) return ClasspathEntry . K_OUTPUT ; return - 1 ; } static String kindToString ( int kind ) { switch ( kind ) { case IClasspathEntry . CPE_PROJECT : return "src" ; case IClasspathEntry . CPE_SOURCE : return "src" ; case IClasspathEntry . CPE_LIBRARY : return "lib" ; case IClasspathEntry . CPE_VARIABLE : return "var" ; case IClasspathEntry . CPE_CONTAINER : return "con" ; case ClasspathEntry . K_OUTPUT : return "output" ; default : return "unknown" ; } } public static IAccessRule [ ] getAccessRules ( IPath [ ] accessibleFiles , IPath [ ] nonAccessibleFiles ) { int accessibleFilesLength = accessibleFiles == null ? 0 : accessibleFiles . length ; int nonAccessibleFilesLength = nonAccessibleFiles == null ? 0 : nonAccessibleFiles . length ; int length = accessibleFilesLength + nonAccessibleFilesLength ; if ( length == 0 ) return null ; IAccessRule [ ] accessRules = new IAccessRule [ length ] ; for ( int i = 0 ; i < accessibleFilesLength ; i ++ ) { accessRules [ i ] = JavaCore . newAccessRule ( accessibleFiles [ i ] , IAccessRule . K_ACCESSIBLE ) ; } for ( int i = 0 ; i < nonAccessibleFilesLength ; i ++ ) { accessRules [ accessibleFilesLength + i ] = JavaCore . newAccessRule ( nonAccessibleFiles [ i ] , IAccessRule . K_NON_ACCESSIBLE ) ; } return accessRules ; } public String toString ( ) { StringBuffer buffer = new StringBuffer ( ) ; Object target = JavaModel . getTarget ( getPath ( ) , true ) ; if ( target instanceof File ) buffer . append ( getPath ( ) . toOSString ( ) ) ; else buffer . append ( String . valueOf ( getPath ( ) ) ) ; buffer . append ( '[' ) ; switch ( getEntryKind ( ) ) { case IClasspathEntry . CPE_LIBRARY : buffer . append ( "CPE_LIBRARY" ) ; break ; case IClasspathEntry . CPE_PROJECT : buffer . append ( "CPE_PROJECT" ) ; break ; case IClasspathEntry . CPE_SOURCE : buffer . append ( "CPE_SOURCE" ) ; break ; case IClasspathEntry . CPE_VARIABLE : buffer . append ( "CPE_VARIABLE" ) ; break ; case IClasspathEntry . CPE_CONTAINER : buffer . append ( "" ) ; break ; } buffer . append ( "][" ) ; switch ( getContentKind ( ) ) { case IPackageFragmentRoot . K_BINARY : buffer . append ( "K_BINARY" ) ; break ; case IPackageFragmentRoot . K_SOURCE : buffer . append ( "K_SOURCE" ) ; break ; case ClasspathEntry . K_OUTPUT : buffer . append ( "K_OUTPUT" ) ; break ; } buffer . append ( ']' ) ; if ( getSourceAttachmentPath ( ) != null ) { buffer . append ( "[sourcePath:" ) ; buffer . append ( getSourceAttachmentPath ( ) ) ; buffer . append ( ']' ) ; } if ( getSourceAttachmentRootPath ( ) != null ) { buffer . append ( "[rootPath:" ) ; buffer . append ( getSourceAttachmentRootPath ( ) ) ; buffer . append ( ']' ) ; } buffer . append ( "[isExported:" ) ; buffer . append ( this . isExported ) ; buffer . append ( ']' ) ; IPath [ ] patterns = this . inclusionPatterns ; int length ; if ( ( length = patterns == null ? 0 : patterns . length ) > 0 ) { buffer . append ( "[including:" ) ; for ( int i = 0 ; i < length ; i ++ ) { buffer . append ( patterns [ i ] ) ; if ( i != length - 1 ) { buffer . append ( '|' ) ; } } buffer . append ( ']' ) ; } patterns = this . exclusionPatterns ; if ( ( length = patterns == null ? 0 : patterns . length ) > 0 ) { buffer . append ( "[excluding:" ) ; for ( int i = 0 ; i < length ; i ++ ) { buffer . append ( patterns [ i ] ) ; if ( i != length - 1 ) { buffer . append ( '|' ) ; } } buffer . append ( ']' ) ; } if ( this . accessRuleSet != null ) { buffer . append ( '[' ) ; buffer . append ( this . accessRuleSet . toString ( false ) ) ; buffer . append ( ']' ) ; } if ( this . entryKind == CPE_PROJECT ) { buffer . append ( "" ) ; buffer . append ( this . combineAccessRules ) ; buffer . append ( ']' ) ; } if ( getOutputLocation ( ) != null ) { buffer . append ( "[output:" ) ; buffer . append ( getOutputLocation ( ) ) ; buffer . append ( ']' ) ; } if ( ( length = this . extraAttributes == null ? 0 : this . extraAttributes . length ) > 0 ) { buffer . append ( "[attributes:" ) ; for ( int i = 0 ; i < length ; i ++ ) { buffer . append ( this . extraAttributes [ i ] ) ; if ( i != length - 1 ) { buffer . append ( ',' ) ; } } buffer . append ( ']' ) ; } return buffer . toString ( ) ; } public ClasspathEntry resolvedDotDot ( ) { IPath resolvedPath = resolveDotDot ( this . path ) ; if ( resolvedPath == this . path ) return this ; return new ClasspathEntry ( getContentKind ( ) , getEntryKind ( ) , resolvedPath , this . inclusionPatterns , this . exclusionPatterns , getSourceAttachmentPath ( ) , getSourceAttachmentRootPath ( ) , getOutputLocation ( ) , this . getReferencingEntry ( ) , this . isExported , getAccessRules ( ) , this . combineAccessRules , this . extraAttributes ) ; } public ClasspathEntry [ ] resolvedChainedLibraries ( ) { IPath [ ] paths = resolvedChainedLibraries ( getPath ( ) ) ; int length = paths . length ; if ( length == 0 ) return NO_ENTRIES ; ClasspathEntry [ ] result = new ClasspathEntry [ length ] ; for ( int i = 0 ; i < length ; i ++ ) { result [ i ] = new ClasspathEntry ( getContentKind ( ) , getEntryKind ( ) , paths [ i ] , this . inclusionPatterns , this . exclusionPatterns , null , null , getOutputLocation ( ) , this , this . isExported , getAccessRules ( ) , this . combineAccessRules , NO_EXTRA_ATTRIBUTES ) ; } return result ; } public String rootID ( ) { if ( this . rootID == null ) { switch ( this . entryKind ) { case IClasspathEntry . CPE_LIBRARY : this . rootID = "[LIB]" + this . path ; break ; case IClasspathEntry . CPE_PROJECT : this . rootID = "[PRJ]" + this . path ; break ; case IClasspathEntry . CPE_SOURCE : this . rootID = "[SRC]" + this . path ; break ; case IClasspathEntry . CPE_VARIABLE : this . rootID = "[VAR]" + this . path ; break ; case IClasspathEntry . CPE_CONTAINER : this . rootID = "[CON]" + this . path ; break ; default : this . rootID = "" ; break ; } } return this . rootID ; } public IClasspathEntry getResolvedEntry ( ) { return JavaCore . getResolvedClasspathEntry ( this ) ; } public static IJavaModelStatus validateClasspath ( IJavaProject javaProject , IClasspathEntry [ ] rawClasspath , IPath projectOutputLocation ) { IProject project = javaProject . getProject ( ) ; IPath projectPath = project . getFullPath ( ) ; String projectName = javaProject . getElementName ( ) ; if ( projectOutputLocation == null ) { return new JavaModelStatus ( IJavaModelStatusConstants . NULL_PATH ) ; } if ( projectOutputLocation . isAbsolute ( ) ) { if ( ! projectPath . isPrefixOf ( projectOutputLocation ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . PATH_OUTSIDE_PROJECT , javaProject , projectOutputLocation . toString ( ) ) ; } } else { return new JavaModelStatus ( IJavaModelStatusConstants . RELATIVE_PATH , projectOutputLocation ) ; } boolean hasSource = false ; boolean hasLibFolder = false ; if ( rawClasspath == null ) return JavaModelStatus . VERIFIED_OK ; int rawLength = rawClasspath . length ; HashSet pathes = new HashSet ( rawLength ) ; for ( int i = 0 ; i < rawLength ; i ++ ) { IPath entryPath = rawClasspath [ i ] . getPath ( ) ; if ( ! pathes . add ( entryPath ) ) { String entryPathMsg = projectName . equals ( entryPath . segment ( 0 ) ) ? entryPath . removeFirstSegments ( 1 ) . toString ( ) : entryPath . makeRelative ( ) . toString ( ) ; return new JavaModelStatus ( IJavaModelStatusConstants . NAME_COLLISION , Messages . bind ( Messages . classpath_duplicateEntryPath , new String [ ] { entryPathMsg , projectName } ) ) ; } } IClasspathEntry [ ] classpath ; try { classpath = ( ( JavaProject ) javaProject ) . resolveClasspath ( rawClasspath , false , false ) . resolvedClasspath ; } catch ( JavaModelException e ) { return e . getJavaModelStatus ( ) ; } int length = classpath . length ; int outputCount = 1 ; IPath [ ] outputLocations = new IPath [ length + 1 ] ; boolean [ ] allowNestingInOutputLocations = new boolean [ length + 1 ] ; outputLocations [ 0 ] = projectOutputLocation ; IPath potentialNestedOutput = null ; int sourceEntryCount = 0 ; boolean disableExclusionPatterns = JavaCore . DISABLED . equals ( javaProject . getOption ( JavaCore . CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS , true ) ) ; boolean disableCustomOutputLocations = JavaCore . DISABLED . equals ( javaProject . getOption ( JavaCore . CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS , true ) ) ; for ( int i = 0 ; i < length ; i ++ ) { IClasspathEntry resolvedEntry = classpath [ i ] ; if ( disableExclusionPatterns && ( ( resolvedEntry . getInclusionPatterns ( ) != null && resolvedEntry . getInclusionPatterns ( ) . length > 0 ) || ( resolvedEntry . getExclusionPatterns ( ) != null && resolvedEntry . getExclusionPatterns ( ) . length > 0 ) ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . DISABLED_CP_EXCLUSION_PATTERNS , javaProject , resolvedEntry . getPath ( ) ) ; } switch ( resolvedEntry . getEntryKind ( ) ) { case IClasspathEntry . CPE_SOURCE : sourceEntryCount ++ ; IPath customOutput ; if ( ( customOutput = resolvedEntry . getOutputLocation ( ) ) != null ) { if ( disableCustomOutputLocations ) { return new JavaModelStatus ( IJavaModelStatusConstants . DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS , javaProject , resolvedEntry . getPath ( ) ) ; } if ( customOutput . isAbsolute ( ) ) { if ( ! javaProject . getPath ( ) . isPrefixOf ( customOutput ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . PATH_OUTSIDE_PROJECT , javaProject , customOutput . toString ( ) ) ; } } else { return new JavaModelStatus ( IJavaModelStatusConstants . RELATIVE_PATH , customOutput ) ; } if ( Util . indexOfMatchingPath ( customOutput , outputLocations , outputCount ) != - 1 ) { continue ; } outputLocations [ outputCount ++ ] = customOutput ; } } } for ( int i = 1 ; i < outputCount ; i ++ ) { IPath customOutput = outputLocations [ i ] ; int index ; if ( ( index = Util . indexOfEnclosingPath ( customOutput , outputLocations , outputCount ) ) != - 1 && index != i ) { if ( index == 0 ) { if ( potentialNestedOutput == null ) potentialNestedOutput = customOutput ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotNestOutputInOutput , new String [ ] { customOutput . makeRelative ( ) . toString ( ) , outputLocations [ index ] . makeRelative ( ) . toString ( ) } ) ) ; } } } if ( sourceEntryCount <= outputCount - 1 ) { allowNestingInOutputLocations [ 0 ] = true ; } else if ( potentialNestedOutput != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotNestOutputInOutput , new String [ ] { potentialNestedOutput . makeRelative ( ) . toString ( ) , outputLocations [ 0 ] . makeRelative ( ) . toString ( ) } ) ) ; } for ( int i = 0 ; i < length ; i ++ ) { IClasspathEntry resolvedEntry = classpath [ i ] ; IPath path = resolvedEntry . getPath ( ) ; int index ; switch ( resolvedEntry . getEntryKind ( ) ) { case IClasspathEntry . CPE_SOURCE : hasSource = true ; if ( ( index = Util . indexOfMatchingPath ( path , outputLocations , outputCount ) ) != - 1 ) { allowNestingInOutputLocations [ index ] = true ; } break ; case IClasspathEntry . CPE_LIBRARY : Object target = JavaModel . getTarget ( path , false ) ; hasLibFolder |= target instanceof IContainer ; if ( ( index = Util . indexOfMatchingPath ( path , outputLocations , outputCount ) ) != - 1 ) { allowNestingInOutputLocations [ index ] = true ; } break ; } } if ( ! hasSource && ! hasLibFolder ) { for ( int i = 0 ; i < outputCount ; i ++ ) allowNestingInOutputLocations [ i ] = true ; } for ( int i = 0 ; i < length ; i ++ ) { IClasspathEntry entry = classpath [ i ] ; if ( entry == null ) continue ; IPath entryPath = entry . getPath ( ) ; int kind = entry . getEntryKind ( ) ; if ( entryPath . equals ( projectPath ) ) { if ( kind == IClasspathEntry . CPE_PROJECT ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_PATH , Messages . bind ( Messages . classpath_cannotReferToItself , entryPath . makeRelative ( ) . toString ( ) ) ) ; } continue ; } if ( kind == IClasspathEntry . CPE_SOURCE || ( kind == IClasspathEntry . CPE_LIBRARY && ( JavaModel . getTarget ( entryPath , false ) instanceof IContainer ) ) ) { for ( int j = 0 ; j < classpath . length ; j ++ ) { IClasspathEntry otherEntry = classpath [ j ] ; if ( otherEntry == null ) continue ; int otherKind = otherEntry . getEntryKind ( ) ; IPath otherPath = otherEntry . getPath ( ) ; if ( entry != otherEntry && ( otherKind == IClasspathEntry . CPE_SOURCE || ( otherKind == IClasspathEntry . CPE_LIBRARY && ( JavaModel . getTarget ( otherPath , false ) instanceof IContainer ) ) ) ) { char [ ] [ ] inclusionPatterns , exclusionPatterns ; if ( otherPath . isPrefixOf ( entryPath ) && ! otherPath . equals ( entryPath ) && ! Util . isExcluded ( entryPath . append ( "*" ) , inclusionPatterns = ( ( ClasspathEntry ) otherEntry ) . fullInclusionPatternChars ( ) , exclusionPatterns = ( ( ClasspathEntry ) otherEntry ) . fullExclusionPatternChars ( ) , false ) ) { String exclusionPattern = entryPath . removeFirstSegments ( otherPath . segmentCount ( ) ) . segment ( 0 ) ; if ( Util . isExcluded ( entryPath , inclusionPatterns , exclusionPatterns , false ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_mustEndWithSlash , new String [ ] { exclusionPattern , entryPath . makeRelative ( ) . toString ( ) } ) ) ; } else { if ( otherKind == IClasspathEntry . CPE_SOURCE ) { exclusionPattern += '/' ; if ( ! disableExclusionPatterns ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotNestEntryInEntry , new String [ ] { entryPath . makeRelative ( ) . toString ( ) , otherEntry . getPath ( ) . makeRelative ( ) . toString ( ) , exclusionPattern } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotNestEntryInEntryNoExclusion , new String [ ] { entryPath . makeRelative ( ) . toString ( ) , otherEntry . getPath ( ) . makeRelative ( ) . toString ( ) , exclusionPattern } ) ) ; } } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotNestEntryInLibrary , new String [ ] { entryPath . makeRelative ( ) . toString ( ) , otherEntry . getPath ( ) . makeRelative ( ) . toString ( ) } ) ) ; } } } } } } char [ ] [ ] inclusionPatterns = ( ( ClasspathEntry ) entry ) . fullInclusionPatternChars ( ) ; char [ ] [ ] exclusionPatterns = ( ( ClasspathEntry ) entry ) . fullExclusionPatternChars ( ) ; for ( int j = 0 ; j < outputCount ; j ++ ) { IPath currentOutput = outputLocations [ j ] ; if ( entryPath . equals ( currentOutput ) ) continue ; if ( entryPath . isPrefixOf ( currentOutput ) ) { if ( kind != IClasspathEntry . CPE_SOURCE || ! Util . isExcluded ( currentOutput , inclusionPatterns , exclusionPatterns , true ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotNestOutputInEntry , new String [ ] { currentOutput . makeRelative ( ) . toString ( ) , entryPath . makeRelative ( ) . toString ( ) } ) ) ; } } } for ( int j = 0 ; j < outputCount ; j ++ ) { if ( allowNestingInOutputLocations [ j ] ) continue ; IPath currentOutput = outputLocations [ j ] ; if ( currentOutput . isPrefixOf ( entryPath ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotNestEntryInOutput , new String [ ] { entryPath . makeRelative ( ) . toString ( ) , currentOutput . makeRelative ( ) . toString ( ) } ) ) ; } } } for ( int i = 0 ; i < length ; i ++ ) { IClasspathEntry entry = classpath [ i ] ; if ( entry == null ) continue ; IPath entryPath = entry . getPath ( ) ; int kind = entry . getEntryKind ( ) ; boolean isProjectRelative = projectName . equals ( entryPath . segment ( 0 ) ) ; String entryPathMsg = isProjectRelative ? entryPath . removeFirstSegments ( 1 ) . toString ( ) : entryPath . makeRelative ( ) . toString ( ) ; if ( kind == IClasspathEntry . CPE_SOURCE ) { IPath output = entry . getOutputLocation ( ) ; if ( output == null ) continue ; for ( int j = 0 ; j < length ; j ++ ) { IClasspathEntry otherEntry = classpath [ j ] ; if ( otherEntry == entry ) continue ; boolean opStartsWithProject = projectName . equals ( otherEntry . getPath ( ) . segment ( 0 ) ) ; String otherPathMsg = opStartsWithProject ? otherEntry . getPath ( ) . removeFirstSegments ( 1 ) . toString ( ) : otherEntry . getPath ( ) . makeRelative ( ) . toString ( ) ; switch ( otherEntry . getEntryKind ( ) ) { case IClasspathEntry . CPE_SOURCE : if ( otherEntry . getPath ( ) . equals ( output ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotUseDistinctSourceFolderAsOutput , new String [ ] { entryPathMsg , otherPathMsg , projectName } ) ) ; } break ; case IClasspathEntry . CPE_LIBRARY : if ( otherEntry . getPath ( ) . equals ( output ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_cannotUseLibraryAsOutput , new String [ ] { entryPathMsg , otherPathMsg , projectName } ) ) ; } } } } } return JavaModelStatus . VERIFIED_OK ; } public static IJavaModelStatus validateClasspathEntry ( IJavaProject project , IClasspathEntry entry , boolean checkSourceAttachment , boolean referredByContainer ) { IJavaModelStatus status = validateClasspathEntry ( project , entry , null , checkSourceAttachment , referredByContainer ) ; int statusCode = status . getCode ( ) ; if ( ( statusCode == IJavaModelStatusConstants . INVALID_CLASSPATH || statusCode == IJavaModelStatusConstants . CP_CONTAINER_PATH_UNBOUND || statusCode == IJavaModelStatusConstants . CP_VARIABLE_PATH_UNBOUND || statusCode == IJavaModelStatusConstants . INVALID_PATH ) && ( ( ClasspathEntry ) entry ) . isOptional ( ) ) return JavaModelStatus . VERIFIED_OK ; return status ; } private static IJavaModelStatus validateClasspathEntry ( IJavaProject project , IClasspathEntry entry , IClasspathContainer entryContainer , boolean checkSourceAttachment , boolean referredByContainer ) { IPath path = entry . getPath ( ) ; String projectName = project . getElementName ( ) ; String entryPathMsg = projectName . equals ( path . segment ( 0 ) ) ? path . removeFirstSegments ( 1 ) . makeRelative ( ) . toString ( ) : path . toString ( ) ; switch ( entry . getEntryKind ( ) ) { case IClasspathEntry . CPE_CONTAINER : if ( path . segmentCount ( ) >= 1 ) { try { IJavaModelStatus status = null ; IClasspathAttribute [ ] extraAttributes = entry . getExtraAttributes ( ) ; if ( extraAttributes != null ) { int length = extraAttributes . length ; HashSet set = new HashSet ( length ) ; for ( int i = 0 ; i < length ; i ++ ) { String attName = extraAttributes [ i ] . getName ( ) ; if ( ! set . add ( attName ) ) { status = new JavaModelStatus ( IJavaModelStatusConstants . NAME_COLLISION , Messages . bind ( Messages . classpath_duplicateEntryExtraAttribute , new String [ ] { attName , entryPathMsg , projectName } ) ) ; break ; } } } IClasspathContainer container = JavaModelManager . getJavaModelManager ( ) . getClasspathContainer ( path , project ) ; if ( container == null ) { if ( status != null ) return status ; return new JavaModelStatus ( IJavaModelStatusConstants . CP_CONTAINER_PATH_UNBOUND , project , path ) ; } else if ( container == JavaModelManager . CONTAINER_INITIALIZATION_IN_PROGRESS ) { return JavaModelStatus . VERIFIED_OK ; } IClasspathEntry [ ] containerEntries = container . getClasspathEntries ( ) ; if ( containerEntries != null ) { for ( int i = 0 , length = containerEntries . length ; i < length ; i ++ ) { IClasspathEntry containerEntry = containerEntries [ i ] ; int kind = containerEntry == null ? 0 : containerEntry . getEntryKind ( ) ; if ( containerEntry == null || kind == IClasspathEntry . CPE_SOURCE || kind == IClasspathEntry . CPE_VARIABLE || kind == IClasspathEntry . CPE_CONTAINER ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CP_CONTAINER_ENTRY , project , path ) ; } IJavaModelStatus containerEntryStatus = validateClasspathEntry ( project , containerEntry , container , checkSourceAttachment , true ) ; if ( ! containerEntryStatus . isOK ( ) ) { return containerEntryStatus ; } } } } catch ( JavaModelException e ) { return new JavaModelStatus ( e ) ; } } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_illegalContainerPath , new String [ ] { entryPathMsg , projectName } ) ) ; } break ; case IClasspathEntry . CPE_VARIABLE : if ( path . segmentCount ( ) >= 1 ) { try { entry = JavaCore . getResolvedClasspathEntry ( entry ) ; } catch ( AssertionFailedException e ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_PATH , e . getMessage ( ) ) ; } if ( entry == null ) { return new JavaModelStatus ( IJavaModelStatusConstants . CP_VARIABLE_PATH_UNBOUND , project , path ) ; } IJavaModelStatus status = validateClasspathEntry ( project , entry , null , checkSourceAttachment , false ) ; if ( ! status . isOK ( ) ) return status ; String variableName = path . segment ( 0 ) ; String deprecatedMessage = JavaCore . getClasspathVariableDeprecationMessage ( variableName ) ; if ( deprecatedMessage != null ) { return new JavaModelStatus ( IStatus . WARNING , IJavaModelStatusConstants . DEPRECATED_VARIABLE , project , path , deprecatedMessage ) ; } return status ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_illegalVariablePath , new String [ ] { entryPathMsg , projectName } ) ) ; } case IClasspathEntry . CPE_LIBRARY : path = ClasspathEntry . resolveDotDot ( path ) ; String containerInfo = null ; if ( entryContainer != null ) { if ( entryContainer instanceof UserLibraryClasspathContainer ) { containerInfo = Messages . bind ( Messages . classpath_userLibraryInfo , new String [ ] { entryContainer . getDescription ( ) } ) ; } else { containerInfo = Messages . bind ( Messages . classpath_containerInfo , new String [ ] { entryContainer . getDescription ( ) } ) ; } } IJavaModelStatus status = validateLibraryEntry ( path , project , containerInfo , checkSourceAttachment ? entry . getSourceAttachmentPath ( ) : null , entryPathMsg ) ; if ( status . getCode ( ) == IJavaModelStatusConstants . INVALID_CLASSPATH && ( ( ClasspathEntry ) entry ) . isOptional ( ) ) status = JavaModelStatus . VERIFIED_OK ; if ( ! status . isOK ( ) ) return status ; break ; case IClasspathEntry . CPE_PROJECT : if ( path . isAbsolute ( ) && path . segmentCount ( ) == 1 ) { IProject prereqProjectRsc = workspaceRoot . getProject ( path . segment ( 0 ) ) ; IJavaProject prereqProject = JavaCore . create ( prereqProjectRsc ) ; try { if ( ! prereqProjectRsc . exists ( ) || ! prereqProjectRsc . hasNature ( JavaCore . NATURE_ID ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundProject , new String [ ] { path . segment ( 0 ) , projectName } ) ) ; } if ( ! prereqProjectRsc . isOpen ( ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_closedProject , new String [ ] { path . segment ( 0 ) } ) ) ; } if ( ! JavaCore . IGNORE . equals ( project . getOption ( JavaCore . CORE_INCOMPATIBLE_JDK_LEVEL , true ) ) ) { long projectTargetJDK = CompilerOptions . versionToJdkLevel ( project . getOption ( JavaCore . COMPILER_CODEGEN_TARGET_PLATFORM , true ) ) ; long prereqProjectTargetJDK = CompilerOptions . versionToJdkLevel ( prereqProject . getOption ( JavaCore . COMPILER_CODEGEN_TARGET_PLATFORM , true ) ) ; if ( prereqProjectTargetJDK > projectTargetJDK ) { return new JavaModelStatus ( IJavaModelStatusConstants . INCOMPATIBLE_JDK_LEVEL , project , path , Messages . bind ( Messages . classpath_incompatibleLibraryJDKLevel , new String [ ] { project . getElementName ( ) , CompilerOptions . versionFromJdkLevel ( projectTargetJDK ) , path . makeRelative ( ) . toString ( ) , CompilerOptions . versionFromJdkLevel ( prereqProjectTargetJDK ) } ) ) ; } } } catch ( CoreException e ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundProject , new String [ ] { path . segment ( 0 ) , projectName } ) ) ; } } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_illegalProjectPath , new String [ ] { path . toString ( ) , projectName } ) ) ; } break ; case IClasspathEntry . CPE_SOURCE : if ( ( ( entry . getInclusionPatterns ( ) != null && entry . getInclusionPatterns ( ) . length > 0 ) || ( entry . getExclusionPatterns ( ) != null && entry . getExclusionPatterns ( ) . length > 0 ) ) && JavaCore . DISABLED . equals ( project . getOption ( JavaCore . CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS , true ) ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . DISABLED_CP_EXCLUSION_PATTERNS , project , path ) ; } if ( entry . getOutputLocation ( ) != null && JavaCore . DISABLED . equals ( project . getOption ( JavaCore . CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS , true ) ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS , project , path ) ; } if ( path . isAbsolute ( ) && ! path . isEmpty ( ) ) { IPath projectPath = project . getProject ( ) . getFullPath ( ) ; if ( ! projectPath . isPrefixOf ( path ) || JavaModel . getTarget ( path , true ) == null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundSourceFolder , new String [ ] { entryPathMsg , projectName } ) ) ; } } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_illegalSourceFolderPath , new String [ ] { entryPathMsg , projectName } ) ) ; } break ; } IClasspathAttribute [ ] extraAttributes = entry . getExtraAttributes ( ) ; if ( extraAttributes != null ) { int length = extraAttributes . length ; HashSet set = new HashSet ( length ) ; for ( int i = 0 ; i < length ; i ++ ) { String attName = extraAttributes [ i ] . getName ( ) ; if ( ! set . add ( attName ) ) { return new JavaModelStatus ( IJavaModelStatusConstants . NAME_COLLISION , Messages . bind ( Messages . classpath_duplicateEntryExtraAttribute , new String [ ] { attName , entryPathMsg , projectName } ) ) ; } } } return JavaModelStatus . VERIFIED_OK ; } private static IJavaModelStatus validateLibraryEntry ( IPath path , IJavaProject project , String container , IPath sourceAttachment , String entryPathMsg ) { if ( path . isAbsolute ( ) && ! path . isEmpty ( ) ) { Object target = JavaModel . getTarget ( path , true ) ; if ( target == null ) { IPath workspaceLocation = workspaceRoot . getLocation ( ) ; if ( workspaceLocation . isPrefixOf ( path ) ) { target = JavaModel . getTarget ( path . makeRelativeTo ( workspaceLocation ) . makeAbsolute ( ) , true ) ; } } if ( target != null && ! JavaCore . IGNORE . equals ( project . getOption ( JavaCore . CORE_INCOMPATIBLE_JDK_LEVEL , true ) ) ) { long projectTargetJDK = CompilerOptions . versionToJdkLevel ( project . getOption ( JavaCore . COMPILER_CODEGEN_TARGET_PLATFORM , true ) ) ; long libraryJDK = Util . getJdkLevel ( target ) ; if ( libraryJDK != 0 && libraryJDK > projectTargetJDK ) { if ( container != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INCOMPATIBLE_JDK_LEVEL , project , path , Messages . bind ( Messages . classpath_incompatibleLibraryJDKLevelInContainer , new String [ ] { project . getElementName ( ) , CompilerOptions . versionFromJdkLevel ( projectTargetJDK ) , path . makeRelative ( ) . toString ( ) , container , CompilerOptions . versionFromJdkLevel ( libraryJDK ) } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INCOMPATIBLE_JDK_LEVEL , project , path , Messages . bind ( Messages . classpath_incompatibleLibraryJDKLevel , new String [ ] { project . getElementName ( ) , CompilerOptions . versionFromJdkLevel ( projectTargetJDK ) , path . makeRelative ( ) . toString ( ) , CompilerOptions . versionFromJdkLevel ( libraryJDK ) } ) ) ; } } } if ( target instanceof IResource ) { IResource resolvedResource = ( IResource ) target ; switch ( resolvedResource . getType ( ) ) { case IResource . FILE : if ( sourceAttachment != null && ! sourceAttachment . isEmpty ( ) && JavaModel . getTarget ( sourceAttachment , true ) == null ) { if ( container != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundSourceAttachmentInContainedLibrary , new String [ ] { sourceAttachment . toString ( ) , path . toString ( ) , container } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundSourceAttachment , new String [ ] { sourceAttachment . toString ( ) , path . toString ( ) , project . getElementName ( ) } ) ) ; } } break ; case IResource . FOLDER : if ( sourceAttachment != null && ! sourceAttachment . isEmpty ( ) && JavaModel . getTarget ( sourceAttachment , true ) == null ) { if ( container != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundSourceAttachmentInContainedLibrary , new String [ ] { sourceAttachment . toString ( ) , path . toString ( ) , container } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundSourceAttachment , new String [ ] { sourceAttachment . toString ( ) , path . toString ( ) , project . getElementName ( ) } ) ) ; } } } } else if ( target instanceof File ) { File file = JavaModel . getFile ( target ) ; if ( file == null ) { if ( container != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_illegalExternalFolderInContainer , new String [ ] { path . toOSString ( ) , container } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_illegalExternalFolder , new String [ ] { path . toOSString ( ) , project . getElementName ( ) } ) ) ; } } else if ( sourceAttachment != null && ! sourceAttachment . isEmpty ( ) && JavaModel . getTarget ( sourceAttachment , true ) == null ) { if ( container != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundSourceAttachmentInContainedLibrary , new String [ ] { sourceAttachment . toString ( ) , path . toOSString ( ) , container } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundSourceAttachment , new String [ ] { sourceAttachment . toString ( ) , path . toOSString ( ) , project . getElementName ( ) } ) ) ; } } } else { boolean isExternal = path . getDevice ( ) != null || ! ResourcesPlugin . getWorkspace ( ) . getRoot ( ) . getProject ( path . segment ( 0 ) ) . exists ( ) ; if ( isExternal ) { if ( container != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundLibraryInContainer , new String [ ] { path . toOSString ( ) , container } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundLibrary , new String [ ] { path . toOSString ( ) , project . getElementName ( ) } ) ) ; } } else { if ( entryPathMsg == null ) entryPathMsg = project . getElementName ( ) . equals ( path . segment ( 0 ) ) ? path . removeFirstSegments ( 1 ) . makeRelative ( ) . toString ( ) : path . toString ( ) ; if ( container != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundLibraryInContainer , new String [ ] { entryPathMsg , container } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_unboundLibrary , new String [ ] { entryPathMsg , project . getElementName ( ) } ) ) ; } } } } else { if ( entryPathMsg == null ) entryPathMsg = project . getElementName ( ) . equals ( path . segment ( 0 ) ) ? path . removeFirstSegments ( 1 ) . makeRelative ( ) . toString ( ) : path . toString ( ) ; if ( container != null ) { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_illegalLibraryPathInContainer , new String [ ] { entryPathMsg , container } ) ) ; } else { return new JavaModelStatus ( IJavaModelStatusConstants . INVALID_CLASSPATH , Messages . bind ( Messages . classpath_illegalLibraryPath , new String [ ] { entryPathMsg , project . getElementName ( ) } ) ) ; } } return JavaModelStatus . VERIFIED_OK ; } } </s>