Source Code Cross Referenced for PolicyUtils.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » security » fortress » 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 » Apache Harmony Java SE » org package » org.apache.harmony.security.fortress 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        /**
019:         * @author Alexey V. Varlamov
020:         * @version $Revision$
021:         */package org.apache.harmony.security.fortress;
022:
023:        import java.io.File;
024:        import java.io.InputStream;
025:        import java.lang.reflect.Constructor;
026:        import java.net.URI;
027:        import java.net.URISyntaxException;
028:        import java.net.URL;
029:        import java.security.AccessController;
030:        import java.security.Permission;
031:        import java.security.PermissionCollection;
032:        import java.security.Permissions;
033:        import java.security.PrivilegedAction;
034:        import java.security.PrivilegedExceptionAction;
035:        import java.security.Security;
036:        import java.util.ArrayList;
037:        import java.util.Collection;
038:        import java.util.Iterator;
039:        import java.util.List;
040:        import java.util.Properties;
041:
042:        import org.apache.harmony.security.Util;
043:        import org.apache.harmony.security.internal.nls.Messages;
044:
045:        /**
046:         * This class consist of a number of static methods, which provide a common functionality 
047:         * for various policy and configuration providers. 
048:         * 
049:         */
050:        public class PolicyUtils {
051:
052:            // No reason to instantiate
053:            private PolicyUtils() {
054:            }
055:
056:            /**
057:             * Auxiliary action for opening InputStream from specified location.
058:             */
059:            public static class URLLoader implements 
060:                    PrivilegedExceptionAction<InputStream> {
061:
062:                /** 
063:                 * URL of target location. 
064:                 */
065:                public URL location;
066:
067:                /**
068:                 *  Constructor with target URL parameter. 
069:                 */
070:                public URLLoader(URL location) {
071:                    this .location = location;
072:                }
073:
074:                /** 
075:                 * Returns InputStream from the target URL.
076:                 */
077:                public InputStream run() throws Exception {
078:                    return location.openStream();
079:                }
080:            }
081:
082:            /** 
083:             * Auxiliary action for accessing system properties in a bundle. 
084:             */
085:            public static class SystemKit implements 
086:                    PrivilegedAction<Properties> {
087:
088:                /** 
089:                 * Returns system properties.
090:                 */
091:                public Properties run() {
092:                    return System.getProperties();
093:                }
094:            }
095:
096:            /** 
097:             * Auxiliary action for accessing specific system property. 
098:             */
099:            public static class SystemPropertyAccessor implements 
100:                    PrivilegedAction<String> {
101:
102:                /** 
103:                 * A key of a required system property.
104:                 */
105:                public String key;
106:
107:                /** 
108:                 * Constructor with a property key parameter. 
109:                 */
110:                public SystemPropertyAccessor(String key) {
111:                    this .key = key;
112:                }
113:
114:                /** 
115:                 * Handy one-line replacement of 
116:                 * &quot;provide key and supply action&quot; code block, 
117:                 * for reusing existing action instance. 
118:                 */
119:                public PrivilegedAction<String> key(String key) {
120:                    this .key = key;
121:                    return this ;
122:                }
123:
124:                /** 
125:                 * Returns specified system property. 
126:                 */
127:                public String run() {
128:                    return System.getProperty(key);
129:                }
130:            }
131:
132:            /** 
133:             * Auxiliary action for accessing specific security property. 
134:             */
135:            public static class SecurityPropertyAccessor implements 
136:                    PrivilegedAction<String> {
137:
138:                private String key;
139:
140:                /** 
141:                 * Constructor with a property key parameter. 
142:                 */
143:                public SecurityPropertyAccessor(String key) {
144:                    super ();
145:                    this .key = key;
146:                }
147:
148:                public PrivilegedAction<String> key(String key) {
149:                    this .key = key;
150:                    return this ;
151:                }
152:
153:                /** 
154:                 * Returns specified security property. 
155:                 */
156:                public String run() {
157:                    return Security.getProperty(key);
158:                }
159:            }
160:
161:            /** 
162:             * Auxiliary action for loading a provider by specific security property.
163:             */
164:            public static class ProviderLoader<T> implements 
165:                    PrivilegedAction<T> {
166:
167:                private String key;
168:
169:                /**
170:                 * Acceptable provider superclass.
171:                 */
172:                private Class<T> expectedType;
173:
174:                /** 
175:                 * Constructor taking property key and acceptable provider 
176:                 * superclass parameters.
177:                 */
178:                public ProviderLoader(String key, Class<T> expected) {
179:                    super ();
180:                    this .key = key;
181:                    this .expectedType = expected;
182:                }
183:
184:                /** 
185:                 * Returns provider instance by specified security property.
186:                 * The <code>key</code> should map to a fully qualified classname.
187:                 * 
188:                 * @throws SecurityException if no value specified for the key 
189:                 * in security properties or if an Exception has occurred 
190:                 * during classloading and instantiating.
191:                 */
192:                public T run() {
193:                    String klassName = Security.getProperty(key);
194:                    if (klassName == null || klassName.length() == 0) {
195:                        throw new SecurityException(Messages.getString(
196:                                "security.14C", //$NON-NLS-1$
197:                                key));
198:                    }
199:                    // TODO accurate classloading
200:                    try {
201:                        Class<?> klass = Class.forName(klassName, true, Thread
202:                                .currentThread().getContextClassLoader());
203:                        if (expectedType != null
204:                                && klass.isAssignableFrom(expectedType)) {
205:                            throw new SecurityException(Messages.getString(
206:                                    "security.14D", //$NON-NLS-1$
207:                                    klassName, expectedType.getName()));
208:                        }
209:                        //FIXME expectedType.cast(klass.newInstance());
210:                        return (T) klass.newInstance();
211:                    } catch (SecurityException se) {
212:                        throw se;
213:                    } catch (Exception e) {
214:                        // TODO log error ??
215:                        SecurityException se = new SecurityException(Messages
216:                                .getString("security.14E", klassName)); //$NON-NLS-1$
217:                        se.initCause(e);
218:                        throw se;
219:                    }
220:                }
221:            }
222:
223:            /** 
224:             * Specific exception to signal that property expansion failed 
225:             * due to unknown key. 
226:             */
227:            public static class ExpansionFailedException extends Exception {
228:
229:                /**
230:                 * @serial
231:                 */
232:                private static final long serialVersionUID = 2869748055182612000L;
233:
234:                /** 
235:                 * Constructor with user-friendly message parameter. 
236:                 */
237:                public ExpansionFailedException(String message) {
238:                    super (message);
239:                }
240:
241:                /** 
242:                 * Constructor with user-friendly message and causing error. 
243:                 */
244:                public ExpansionFailedException(String message, Throwable cause) {
245:                    super (message, cause);
246:                }
247:            }
248:
249:            /**
250:             * Substitutes all entries like ${some.key}, found in specified string, 
251:             * for specified values.
252:             * If some key is unknown, throws ExpansionFailedException. 
253:             * @param str the string to be expanded
254:             * @param properties available key-value mappings 
255:             * @return expanded string
256:             * @throws ExpansionFailedException
257:             */
258:            public static String expand(String str, Properties properties)
259:                    throws ExpansionFailedException {
260:                final String START_MARK = "${"; //$NON-NLS-1$
261:                final String END_MARK = "}"; //$NON-NLS-1$
262:                final int START_OFFSET = START_MARK.length();
263:                final int END_OFFSET = END_MARK.length();
264:
265:                StringBuilder result = new StringBuilder(str);
266:                int start = result.indexOf(START_MARK);
267:                while (start >= 0) {
268:                    int end = result.indexOf(END_MARK, start);
269:                    if (end >= 0) {
270:                        String key = result
271:                                .substring(start + START_OFFSET, end);
272:                        String value = properties.getProperty(key);
273:                        if (value != null) {
274:                            result.replace(start, end + END_OFFSET, value);
275:                            start += value.length();
276:                        } else {
277:                            throw new ExpansionFailedException(Messages
278:                                    .getString("security.14F", key)); //$NON-NLS-1$
279:                        }
280:                    }
281:                    start = result.indexOf(START_MARK, start);
282:                }
283:                return result.toString();
284:            }
285:
286:            /**
287:             * Handy shortcut for 
288:             * <code>expand(str, properties).replace(File.separatorChar, '/')</code>.
289:             * @see #expand(String, Properties)
290:             */
291:            public static String expandURL(String str, Properties properties)
292:                    throws ExpansionFailedException {
293:                return expand(str, properties).replace(File.separatorChar, '/');
294:            }
295:
296:            /**
297:             * Normalizes URLs to standard ones, eliminating pathname symbols.
298:             * 
299:             * @param codebase -
300:             *            the original URL.
301:             * @return - the normalized URL.
302:             */
303:            public static URL normalizeURL(URL codebase) {
304:                if (codebase != null && "file".equals(codebase.getProtocol())) { //$NON-NLS-1$
305:                    try {
306:                        if (codebase.getHost().length() == 0) {
307:                            String path = codebase.getFile();
308:
309:                            if (path.length() == 0) {
310:                                // codebase is "file:"
311:                                path = "*";
312:                            }
313:                            return filePathToURI(
314:                                    new File(path).getAbsolutePath())
315:                                    .normalize().toURL();
316:                        } else {
317:                            // codebase is "file://<smth>"
318:                            return codebase.toURI().normalize().toURL();
319:                        }
320:                    } catch (Exception e) {
321:                        // Ignore
322:                    }
323:                }
324:                return codebase;
325:            }
326:
327:            /**
328:             * Converts a file path to URI without accessing file system
329:             * (like {File#toURI()} does).
330:             * 
331:             * @param path -
332:             *            file path.
333:             * @return - the resulting URI.
334:             * @throw URISyntaxException
335:             */
336:            public static URI filePathToURI(String path)
337:                    throws URISyntaxException {
338:                path = path.replace(File.separatorChar, '/');
339:
340:                if (!path.startsWith("/")) { //$NON-NLS-1$
341:                    return new URI("file", null, //$NON-NLS-1$
342:                            new StringBuilder(path.length() + 1).append('/')
343:                                    .append(path).toString(), null, null);
344:                }
345:                return new URI("file", null, path, null, null); //$NON-NLS-1$
346:            }
347:
348:            /**
349:             * Instances of this interface are intended for resolving  
350:             * generalized expansion expressions, of the form ${{protocol:data}}. 
351:             * Such functionality is applicable to security policy files, for example.
352:             * @see org.apache.harmony.security.PolicyUtils#expandGeneral(String, GeneralExpansionHandler)
353:             */
354:            public static interface GeneralExpansionHandler {
355:
356:                /**
357:                 * Resolves general expansion expressions of the form ${{protocol:data}}.
358:                 * @param protocol denotes type of resolution
359:                 * @param data data to be resolved, optional (may be null)
360:                 * @return resolved value, must not be null
361:                 * @throws PolicyUtils.ExpansionFailedException if expansion is impossible
362:                 */
363:                String resolve(String protocol, String data)
364:                        throws ExpansionFailedException;
365:            }
366:
367:            /**
368:             * Substitutes all entries like ${{protocol:data}}, found in specified string, 
369:             * for values resolved by passed handler.
370:             * The data part may be empty, and in this case expression 
371:             * may have simplified form, as ${{protocol}}.
372:             * If some entry cannot be resolved, throws ExpansionFailedException;
373:             * @param str the string to be expanded
374:             * @param handler the handler to resolve data denoted by protocol  
375:             * @return expanded string
376:             * @throws ExpansionFailedException
377:             */
378:            public static String expandGeneral(String str,
379:                    GeneralExpansionHandler handler)
380:                    throws ExpansionFailedException {
381:                final String START_MARK = "${{"; //$NON-NLS-1$
382:                final String END_MARK = "}}"; //$NON-NLS-1$
383:                final int START_OFFSET = START_MARK.length();
384:                final int END_OFFSET = END_MARK.length();
385:
386:                StringBuilder result = new StringBuilder(str);
387:                int start = result.indexOf(START_MARK);
388:                while (start >= 0) {
389:                    int end = result.indexOf(END_MARK, start);
390:                    if (end >= 0) {
391:                        String key = result
392:                                .substring(start + START_OFFSET, end);
393:                        int separator = key.indexOf(':');
394:                        String protocol = (separator >= 0) ? key.substring(0,
395:                                separator) : key;
396:                        String data = (separator >= 0) ? key
397:                                .substring(separator + 1) : null;
398:                        String value = handler.resolve(protocol, data);
399:                        result.replace(start, end + END_OFFSET, value);
400:                        start += value.length();
401:                    }
402:                    start = result.indexOf(START_MARK, start);
403:                }
404:                return result.toString();
405:            }
406:
407:            /** 
408:             * A key to security properties, deciding whether usage of 
409:             * dynamic policy location via system properties is allowed. 
410:             * @see #getPolicyURLs(Properties, String, String)
411:             */
412:            public static final String POLICY_ALLOW_DYNAMIC = "policy.allowSystemProperty"; //$NON-NLS-1$
413:
414:            /** 
415:             * A key to security properties, deciding whether expansion of 
416:             * system properties is allowed 
417:             * (in security properties values, policy files, etc).
418:             * @see #expand(String, Properties) 
419:             */
420:            public static final String POLICY_EXPAND = "policy.expandProperties"; //$NON-NLS-1$
421:
422:            /** 
423:             * Positive value of switching properties.
424:             */
425:            public static final String TRUE = "true"; //$NON-NLS-1$
426:
427:            /** 
428:             * Negative value of switching properties.
429:             */
430:            public static final String FALSE = "false"; //$NON-NLS-1$
431:
432:            /** 
433:             * Returns false if current security settings disable to perform 
434:             * properties expansion, true otherwise.
435:             * @see #expand(String, Properties)  
436:             */
437:            public static boolean canExpandProperties() {
438:                return !Util.equalsIgnoreCase(FALSE, AccessController
439:                        .doPrivileged(new SecurityPropertyAccessor(
440:                                POLICY_EXPAND)));
441:            }
442:
443:            /**
444:             * Obtains a list of locations for a policy or configuration provider.
445:             * The search algorithm is as follows:
446:             * <ol>
447:             * <li> Look in security properties for keys of form <code>prefix + n</code>, 
448:             * where <i>n</i> is an integer and <i>prefix</i> is a passed parameter. 
449:             * Sequence starts with <code>n=1</code>, and keeps incrementing <i>n</i> 
450:             * until next key is not found. <br> 
451:             * For each obtained key, try to construct an URL instance. On success, 
452:             * add the URL to the list; otherwise ignore it.
453:             * <li>
454:             *         If security settings do not prohibit (through 
455:             *         {@link #POLICY_ALLOW_DYNAMIC the &quot;policy.allowSystemProperty&quot; property}) 
456:             *         to use additional policy location, read the system property under the 
457:             *         passed key parameter. If property exists, it may designate a file or 
458:             *         an absolute URL. Thus, first check if there is a file with that name, 
459:             *         and if so, convert the pathname to URL. Otherwise, try to instantiate   
460:             *         an URL directly. If succeeded, append the URL to the list 
461:             * <li>
462:             *         If the additional location from the step above was specified to the 
463:             *         system via &quot;==&quot; (i.e. starts with '='), discard all URLs above 
464:             *         and use this only URL.
465:             * </ol> 
466:             * <b>Note:</b> all property values (both security and system) related to URLs are
467:             * subject to {@link #expand(String, Properties) property expansion}, regardless 
468:             * of the &quot;policy.expandProperties&quot; security setting.  
469:             * 
470:             * @param system system properties
471:             * @param systemUrlKey key to additional policy location
472:             * @param securityUrlPrefix prefix to numbered locations in security properties
473:             * @return array of URLs to provider's configuration files, may be empty.
474:             */
475:            public static URL[] getPolicyURLs(final Properties system,
476:                    final String systemUrlKey, final String securityUrlPrefix) {
477:
478:                final SecurityPropertyAccessor security = new SecurityPropertyAccessor(
479:                        null);
480:                final List<URL> urls = new ArrayList<URL>();
481:                boolean dynamicOnly = false;
482:                URL dynamicURL = null;
483:
484:                //first check if policy is set via system properties
485:                if (!Util.equalsIgnoreCase(FALSE, AccessController
486:                        .doPrivileged(security.key(POLICY_ALLOW_DYNAMIC)))) {
487:                    String location = system.getProperty(systemUrlKey);
488:                    if (location != null) {
489:                        if (location.startsWith("=")) { //$NON-NLS-1$
490:                            //overrides all other urls
491:                            dynamicOnly = true;
492:                            location = location.substring(1);
493:                        }
494:                        try {
495:                            location = expandURL(location, system);
496:                            // location can be a file, but we need an url...
497:                            final File f = new File(location);
498:                            dynamicURL = AccessController
499:                                    .doPrivileged(new PrivilegedExceptionAction<URL>() {
500:
501:                                        public URL run() throws Exception {
502:                                            if (f.exists()) {
503:                                                return f.toURI().toURL();
504:                                            } else {
505:                                                return null;
506:                                            }
507:                                        }
508:                                    });
509:                            if (dynamicURL == null) {
510:                                dynamicURL = new URL(location);
511:                            }
512:                        } catch (Exception e) {
513:                            // TODO: log error
514:                            // System.err.println("Error detecting system policy location: "+e);
515:                        }
516:                    }
517:                }
518:                //next read urls from security.properties 
519:                if (!dynamicOnly) {
520:                    int i = 1;
521:                    while (true) {
522:                        String location = AccessController
523:                                .doPrivileged(security.key(new StringBuilder(
524:                                        securityUrlPrefix).append(i++)
525:                                        .toString()));
526:                        if (location == null) {
527:                            break;
528:                        }
529:                        try {
530:                            location = expandURL(location, system);
531:                            URL anURL = new URL(location);
532:                            if (anURL != null) {
533:                                urls.add(anURL);
534:                            }
535:                        } catch (Exception e) {
536:                            // TODO: log error
537:                            // System.err.println("Error detecting security policy location: "+e);
538:                        }
539:                    }
540:                }
541:                if (dynamicURL != null) {
542:                    urls.add(dynamicURL);
543:                }
544:                return urls.toArray(new URL[urls.size()]);
545:            }
546:
547:            /** 
548:             * Converts common-purpose collection of Permissions to PermissionCollection.
549:             *
550:             * @param perms a collection containing arbitrary permissions, may be null
551:             * @return mutable heterogeneous PermissionCollection containing all Permissions 
552:             * from the specified collection
553:             */
554:            public static PermissionCollection toPermissionCollection(
555:                    Collection<Permission> perms) {
556:                Permissions pc = new Permissions();
557:                if (perms != null) {
558:                    for (Iterator<Permission> iter = perms.iterator(); iter
559:                            .hasNext();) {
560:                        Permission element = iter.next();
561:                        pc.add(element);
562:                    }
563:                }
564:                return pc;
565:            }
566:
567:            // Empty set of arguments to default constructor of a Permission.
568:            private static final Class[] NO_ARGS = {};
569:
570:            // One-arg set of arguments to default constructor of a Permission.
571:            private static final Class[] ONE_ARGS = { String.class };
572:
573:            // Two-args set of arguments to default constructor of a Permission.
574:            private static final Class[] TWO_ARGS = { String.class,
575:                    String.class };
576:
577:            /**
578:             * Tries to find a suitable constructor and instantiate a new Permission
579:             * with specified parameters.  
580:             *
581:             * @param targetType class of expected Permission instance
582:             * @param targetName name of expected Permission instance
583:             * @param targetActions actions of expected Permission instance
584:             * @return a new Permission instance
585:             * @throws IllegalArgumentException if no suitable constructor found
586:             * @throws Exception any exception thrown by Constructor.newInstance()
587:             */
588:            public static Permission instantiatePermission(Class<?> targetType,
589:                    String targetName, String targetActions) throws Exception {
590:
591:                // let's guess the best order for trying constructors
592:                Class[][] argTypes = null;
593:                Object[][] args = null;
594:                if (targetActions != null) {
595:                    argTypes = new Class[][] { TWO_ARGS, ONE_ARGS, NO_ARGS };
596:                    args = new Object[][] { { targetName, targetActions },
597:                            { targetName }, {} };
598:                } else if (targetName != null) {
599:                    argTypes = new Class[][] { ONE_ARGS, TWO_ARGS, NO_ARGS };
600:                    args = new Object[][] { { targetName },
601:                            { targetName, targetActions }, {} };
602:                } else {
603:                    argTypes = new Class[][] { NO_ARGS, ONE_ARGS, TWO_ARGS };
604:                    args = new Object[][] { {}, { targetName },
605:                            { targetName, targetActions } };
606:                }
607:
608:                // finally try to instantiate actual permission
609:                for (int i = 0; i < argTypes.length; i++) {
610:                    try {
611:                        Constructor<?> ctor = targetType
612:                                .getConstructor(argTypes[i]);
613:                        return (Permission) ctor.newInstance(args[i]);
614:                    } catch (NoSuchMethodException ignore) {
615:                    }
616:                }
617:                throw new IllegalArgumentException(Messages.getString(
618:                        "security.150", targetType));//$NON-NLS-1$
619:            }
620:
621:            /**
622:             * Checks whether the objects from <code>what</code> array are all
623:             * presented in <code>where</code> array.
624:             * 
625:             * @param what first array, may be <code>null</code> 
626:             * @param where  second array, may be <code>null</code>
627:             * @return <code>true</code> if the first array is <code>null</code>
628:             * or if each and every object (ignoring null values) 
629:             * from the first array has a twin in the second array; <code>false</code> otherwise
630:             */
631:            public static boolean matchSubset(Object[] what, Object[] where) {
632:                if (what == null) {
633:                    return true;
634:                }
635:
636:                for (int i = 0; i < what.length; i++) {
637:                    if (what[i] != null) {
638:                        if (where == null) {
639:                            return false;
640:                        }
641:                        boolean found = false;
642:                        for (int j = 0; j < where.length; j++) {
643:                            if (what[i].equals(where[j])) {
644:                                found = true;
645:                                break;
646:                            }
647:                        }
648:                        if (!found) {
649:                            return false;
650:                        }
651:                    }
652:                }
653:                return true;
654:            }
655:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.