| 1 | /******************************************************************************* | 
| 2 |  * Copyright (c) 2009 IBM Corporation and others. | 
| 3 |  * All rights reserved. This program and the accompanying materials | 
| 4 |  * are made available under the terms of the Eclipse Public License v1.0 | 
| 5 |  * which accompanies this distribution, and is available at | 
| 6 |  * http://www.eclipse.org/legal/epl-v10.html | 
| 7 |  * | 
| 8 |  * Contributors: | 
| 9 |  *     IBM Corporation - initial API and implementation | 
| 10 |  *******************************************************************************/ | 
| 11 | package org.eclipse.pde.api.tools.internal.search; | 
| 12 |   | 
| 13 | import java.util.regex.Pattern; | 
| 14 |   | 
| 15 | import org.eclipse.pde.api.tools.internal.provisional.ApiDescriptionVisitor; | 
| 16 | import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations; | 
| 17 | import org.eclipse.pde.api.tools.internal.provisional.IApiDescription; | 
| 18 | import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers; | 
| 19 | import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor; | 
| 20 | import org.eclipse.pde.api.tools.internal.provisional.descriptors.IPackageDescriptor; | 
| 21 |   | 
| 22 | /** | 
| 23 |  * Visits an API description modifying package visibility based on pattern | 
| 24 |  * matching. | 
| 25 |  */ | 
| 26 | public class ApiDescriptionModifier extends ApiDescriptionVisitor { | 
| 27 |          | 
| 28 |         /** | 
| 29 |          * Internal package patterns or <code>null</code> if none. | 
| 30 |          */ | 
| 31 |         private Pattern[] fInternalPackages; | 
| 32 |                  | 
| 33 |         /** | 
| 34 |          * API package patterns of <code>null</code> if none. | 
| 35 |          */ | 
| 36 |         private Pattern[] fApiPackages;  | 
| 37 |          | 
| 38 |         /** | 
| 39 |          * API description to modify. | 
| 40 |          */ | 
| 41 |         private IApiDescription fDescription; | 
| 42 |          | 
| 43 |         /** | 
| 44 |          * Constructs a visitor with the given patterns. | 
| 45 |          *  | 
| 46 |          * @param internal regular expressions to match as internal packages or <code>null</code> | 
| 47 |          * @param api regular expressions to match as API or <code>null</code> | 
| 48 |          */ | 
| 49 |         public ApiDescriptionModifier(String[] internal, String[] api) { | 
| 50 |                 setInternalPatterns(internal); | 
| 51 |                 setApiPatterns(api); | 
| 52 |         } | 
| 53 |          | 
| 54 |         /** | 
| 55 |          * Sets the description to be modified. | 
| 56 |          *  | 
| 57 |          * @param description API description to modify | 
| 58 |          */ | 
| 59 |         public void setApiDescription(IApiDescription description) { | 
| 60 |                 fDescription = description; | 
| 61 |         } | 
| 62 |   | 
| 63 |         /** | 
| 64 |          * Sets regular expressions to consider as internal packages. Used to override visibility settings | 
| 65 |          * in an API description. | 
| 66 |          *  | 
| 67 |          * @param patterns regular expressions, may be empty or <code>null</code> | 
| 68 |          */ | 
| 69 |         private void setInternalPatterns(String[] patterns) { | 
| 70 |                 if (patterns == null || patterns.length == 0) { | 
| 71 |                         fInternalPackages = null; | 
| 72 |                 } else { | 
| 73 |                         fInternalPackages = new Pattern[patterns.length]; | 
| 74 |                         for (int i = 0; i < patterns.length; i++) { | 
| 75 |                                 fInternalPackages[i] = Pattern.compile(patterns[i]); | 
| 76 |                         } | 
| 77 |                 } | 
| 78 |         } | 
| 79 |          | 
| 80 |         /** | 
| 81 |          * Sets regular expressions to consider as API packages. Used to override visibility settings | 
| 82 |          * in an API description. | 
| 83 |          *  | 
| 84 |          * @param patterns regular expressions, may be empty or <code>null</code> | 
| 85 |          */ | 
| 86 |         private void setApiPatterns(String[] patterns) { | 
| 87 |                 if (patterns == null || patterns.length == 0) { | 
| 88 |                         fApiPackages = null; | 
| 89 |                 } else { | 
| 90 |                         fApiPackages = new Pattern[patterns.length]; | 
| 91 |                         for (int i = 0; i < patterns.length; i++) { | 
| 92 |                                 fApiPackages[i] = Pattern.compile(patterns[i]); | 
| 93 |                         } | 
| 94 |                 } | 
| 95 |         } | 
| 96 |          | 
| 97 |         /* (non-Javadoc) | 
| 98 |          * @see org.eclipse.pde.api.tools.internal.provisional.ApiDescriptionVisitor#visitElement(org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor, org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations) | 
| 99 |          */ | 
| 100 |         public boolean visitElement(IElementDescriptor element, IApiAnnotations description) { | 
| 101 |                 switch (element.getElementType()) { | 
| 102 |                         case IElementDescriptor.COMPONENT: | 
| 103 |                                 return true; | 
| 104 |                         case IElementDescriptor.PACKAGE: | 
| 105 |                                 IPackageDescriptor pkg = (IPackageDescriptor) element; | 
| 106 |                                 if (fInternalPackages != null) { | 
| 107 |                                         if (matchesPattern(pkg.getName(), fInternalPackages)) { | 
| 108 |                                                 fDescription.setVisibility(element, VisibilityModifiers.PRIVATE); | 
| 109 |                                         } | 
| 110 |                                 } | 
| 111 |                                 if (fApiPackages != null) { | 
| 112 |                                         if (matchesPattern(pkg.getName(), fApiPackages)) { | 
| 113 |                                                 fDescription.setVisibility(element, VisibilityModifiers.API); | 
| 114 |                                         } | 
| 115 |                                 } | 
| 116 |                                 return false; | 
| 117 |                         default: | 
| 118 |                                 return false; | 
| 119 |                 } | 
| 120 |         } | 
| 121 |          | 
| 122 |         /** | 
| 123 |          * Returns whether the package matches any of the given patterns. | 
| 124 |          *  | 
| 125 |          * @param name name to match | 
| 126 |          * @param patterns patterns to match against | 
| 127 |          * @return whether there's a match | 
| 128 |          */ | 
| 129 |         private boolean matchesPattern(String name, Pattern[] patterns) { | 
| 130 |                 for (int i = 0; i < patterns.length; i++) { | 
| 131 |                         if (patterns[i].matcher(name).find()) { | 
| 132 |                                 return true; | 
| 133 |                         } | 
| 134 |                 } | 
| 135 |                 return false; | 
| 136 |         } | 
| 137 | } |