1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.graalvm.options; 26 27 import java.util.Arrays; 28 import java.util.Collections; 29 import java.util.Iterator; 30 import java.util.NoSuchElementException; 31 32 /** 33 * An interface to a set of {@link OptionDescriptor}s. 34 * 35 * @since 1.0 36 */ 37 public interface OptionDescriptors extends Iterable<OptionDescriptor> { 38 39 /** 40 * An empty set of option descriptors. 41 * 42 * @since 1.0 43 */ 44 OptionDescriptors EMPTY = new OptionDescriptors() { 45 46 public Iterator<OptionDescriptor> iterator() { 47 return Collections.<OptionDescriptor> emptyList().iterator(); 48 } 49 50 public OptionDescriptor get(String key) { 51 return null; 52 } 53 }; 54 55 /** 56 * Gets the {@link OptionDescriptor} matching a given option name or {@code null} if this option 57 * descriptor set doesn't contain a matching option name. 58 * 59 * @since 1.0 60 */ 61 OptionDescriptor get(String optionName); 62 63 /** 64 * Create a union options descriptor out of multiple given descriptors. The operation 65 * descriptors are not checked for duplicate keys. The option descriptors are iterated in 66 * declaration order. 67 * 68 * @since 1.0 69 */ 70 static OptionDescriptors createUnion(OptionDescriptors... descriptors) { 71 if (descriptors.length == 0) { 72 return EMPTY; 73 } else if (descriptors.length == 1) { 74 return descriptors[0]; 75 } else { 76 return new UnionOptionDescriptors(descriptors); 77 } 78 } 79 } 80 81 final class UnionOptionDescriptors implements OptionDescriptors { 82 83 final OptionDescriptors[] descriptorsList; 84 85 UnionOptionDescriptors(OptionDescriptors[] descriptors) { 86 // defensive copy 87 this.descriptorsList = Arrays.copyOf(descriptors, descriptors.length); 88 } 89 90 public Iterator<OptionDescriptor> iterator() { 91 return new Iterator<OptionDescriptor>() { 92 93 Iterator<OptionDescriptor> descriptors = descriptorsList[0].iterator(); 94 int descriptorsIndex = 0; 95 OptionDescriptor next = null; 96 97 public boolean hasNext() { 98 return fetchNext() != null; 99 } 100 101 private OptionDescriptor fetchNext() { 102 if (next != null) { 103 return next; 104 } 105 if (descriptors.hasNext()) { 106 next = descriptors.next(); 107 return next; 108 } else if (descriptorsIndex < descriptorsList.length - 1) { 109 descriptorsIndex++; 110 descriptors = descriptorsList[descriptorsIndex].iterator(); 111 return fetchNext(); 112 } else { 113 return null; 114 } 115 } 116 117 public OptionDescriptor next() { 118 OptionDescriptor fetchedNext = fetchNext(); 119 if (fetchedNext != null) { 120 // consume next 121 this.next = null; 122 return fetchedNext; 123 } else { 124 throw new NoSuchElementException(); 125 } 126 } 127 }; 128 } 129 130 public OptionDescriptor get(String value) { 131 for (OptionDescriptors descriptors : descriptorsList) { 132 OptionDescriptor descriptor = descriptors.get(value); 133 if (descriptor != null) { 134 return descriptor; 135 } 136 } 137 return null; 138 } 139 140 }