Changeset 8243 in josm for trunk/src/com/drew/metadata/Metadata.java
- Timestamp:
- 2015-04-21T00:42:50+02:00 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/com/drew/metadata/Metadata.java
r8132 r8243 37 37 { 38 38 @NotNull 39 private final Map<Class<? extends Directory>,Directory> _directoryByClass = new HashMap<Class<? extends Directory>, Directory>(); 40 41 /** 42 * List of Directory objects set against this object. Keeping a list handy makes 43 * creation of an Iterator and counting tags simple. 44 */ 45 @NotNull 46 private final Collection<Directory> _directoryList = new ArrayList<Directory>(); 47 48 /** 49 * Returns an objects for iterating over Directory objects in the order in which they were added. 50 * 51 * @return an iterable collection of directories 39 private final Map<Class<? extends Directory>,Collection<Directory>> _directoryListByClass = new HashMap<Class<? extends Directory>, Collection<Directory>>(); 40 41 /** 42 * Returns an iterable set of the {@link Directory} instances contained in this metadata collection. 43 * 44 * @return an iterable set of directories 52 45 */ 53 46 @NotNull 54 47 public Iterable<Directory> getDirectories() 55 48 { 56 return Collections.unmodifiableCollection(_directoryList); 57 } 58 59 /** 60 * Returns a count of unique directories in this metadata collection. 49 return new DirectoryIterable(_directoryListByClass); 50 } 51 52 @Nullable 53 public <T extends Directory> Collection<T> getDirectoriesOfType(Class<T> type) 54 { 55 return (Collection<T>)_directoryListByClass.get(type); 56 } 57 58 /** 59 * Returns the count of directories in this metadata collection. 61 60 * 62 61 * @return the number of unique directory types set for this metadata collection … … 64 63 public int getDirectoryCount() 65 64 { 66 return _directoryList.size(); 67 } 68 69 /** 70 * Returns a {@link Directory} of specified type. If this {@link Metadata} object already contains 71 * such a directory, it is returned. Otherwise a new instance of this directory will be created and stored within 72 * this {@link Metadata} object. 73 * 74 * @param type the type of the Directory implementation required. 75 * @return a directory of the specified type. 76 */ 77 @NotNull 65 int count = 0; 66 for (Map.Entry<Class<? extends Directory>,Collection<Directory>> pair : _directoryListByClass.entrySet()) 67 count += pair.getValue().size(); 68 return count; 69 } 70 71 /** 72 * Adds a directory to this metadata collection. 73 * 74 * @param directory the {@link Directory} to add into this metadata collection. 75 */ 76 public <T extends Directory> void addDirectory(@NotNull T directory) 77 { 78 getOrCreateDirectoryList(directory.getClass()).add(directory); 79 } 80 81 /** 82 * Gets the first {@link Directory} of the specified type contained within this metadata collection. 83 * If no instances of this type are present, <code>null</code> is returned. 84 * 85 * @param type the Directory type 86 * @param <T> the Directory type 87 * @return the first Directory of type T in this metadata collection, or <code>null</code> if none exist 88 */ 89 @Nullable 78 90 @SuppressWarnings("unchecked") 79 public <T extends Directory> T get OrCreateDirectory(@NotNull Class<T> type)91 public <T extends Directory> T getFirstDirectoryOfType(@NotNull Class<T> type) 80 92 { 81 93 // We suppress the warning here as the code asserts a map signature of Class<T>,T. 82 94 // So after get(Class<T>) it is for sure the result is from type T. 83 95 84 // check if we've already issued this type of directory 85 if (_directoryByClass.containsKey(type)) 86 return (T)_directoryByClass.get(type); 87 88 T directory; 89 try { 90 directory = type.newInstance(); 91 } catch (Exception e) { 92 throw new RuntimeException("Cannot instantiate provided Directory type: " + type.toString()); 93 } 94 // store the directory 95 _directoryByClass.put(type, directory); 96 _directoryList.add(directory); 97 98 return directory; 99 } 100 101 /** 102 * If this {@link Metadata} object contains a {@link Directory} of the specified type, it is returned. 103 * Otherwise <code>null</code> is returned. 104 * 105 * @param type the Directory type 106 * @param <T> the Directory type 107 * @return a Directory of type T if it exists in this {@link Metadata} object, otherwise <code>null</code>. 108 */ 109 @Nullable 110 @SuppressWarnings("unchecked") 111 public <T extends Directory> T getDirectory(@NotNull Class<T> type) 112 { 113 // We suppress the warning here as the code asserts a map signature of Class<T>,T. 114 // So after get(Class<T>) it is for sure the result is from type T. 115 116 return (T)_directoryByClass.get(type); 117 } 118 119 /** 120 * Indicates whether a given directory type has been created in this metadata 121 * repository. Directories are created by calling {@link Metadata#getOrCreateDirectory(Class)}. 96 Collection<Directory> list = getDirectoryList(type); 97 98 if (list == null || list.isEmpty()) 99 return null; 100 101 return (T)list.iterator().next(); 102 } 103 104 /** 105 * Indicates whether an instance of the given directory type exists in this Metadata instance. 122 106 * 123 107 * @param type the {@link Directory} type 124 * @return true if the {@link Directory} has been created 125 */ 126 public boolean containsDirectory(Class<? extends Directory> type) 127 { 128 return _directoryByClass.containsKey(type); 108 * @return <code>true</code> if a {@link Directory} of the specified type exists, otherwise <code>false</code> 109 */ 110 public boolean containsDirectoryOfType(Class<? extends Directory> type) 111 { 112 Collection<Directory> list = getDirectoryList(type); 113 return list != null && !list.isEmpty(); 129 114 } 130 115 … … 137 122 public boolean hasErrors() 138 123 { 139 for (Directory directory : _directoryList) {124 for (Directory directory : getDirectories()) { 140 125 if (directory.hasErrors()) 141 126 return true; … … 147 132 public String toString() 148 133 { 134 int count = getDirectoryCount(); 149 135 return String.format("Metadata (%d %s)", 150 _directoryList.size(),151 _directoryList.size()== 1136 count, 137 count == 1 152 138 ? "directory" 153 139 : "directories"); 154 140 } 141 142 @Nullable 143 private <T extends Directory> Collection<Directory> getDirectoryList(@NotNull Class<T> type) 144 { 145 return _directoryListByClass.get(type); 146 } 147 148 @NotNull 149 private <T extends Directory> Collection<Directory> getOrCreateDirectoryList(@NotNull Class<T> type) 150 { 151 Collection<Directory> collection = getDirectoryList(type); 152 if (collection != null) 153 return collection; 154 collection = new ArrayList<Directory>(); 155 _directoryListByClass.put(type, collection); 156 return collection; 157 } 158 159 private static class DirectoryIterable implements Iterable<Directory> 160 { 161 private final Map<Class<? extends Directory>, Collection<Directory>> _map; 162 163 public DirectoryIterable(Map<Class<? extends Directory>, Collection<Directory>> map) 164 { 165 _map = map; 166 } 167 168 public Iterator<Directory> iterator() 169 { 170 return new DirectoryIterator(_map); 171 } 172 173 private static class DirectoryIterator implements Iterator<Directory> 174 { 175 @NotNull 176 private final Iterator<Map.Entry<Class<? extends Directory>, Collection<Directory>>> _mapIterator; 177 @Nullable 178 private Iterator<Directory> _listIterator; 179 180 public DirectoryIterator(Map<Class<? extends Directory>, Collection<Directory>> map) 181 { 182 _mapIterator = map.entrySet().iterator(); 183 184 if (_mapIterator.hasNext()) 185 _listIterator = _mapIterator.next().getValue().iterator(); 186 } 187 188 public boolean hasNext() 189 { 190 return _listIterator != null && (_listIterator.hasNext() || _mapIterator.hasNext()); 191 } 192 193 public Directory next() 194 { 195 if (_listIterator == null || (!_listIterator.hasNext() && !_mapIterator.hasNext())) 196 throw new NoSuchElementException(); 197 198 while (!_listIterator.hasNext()) 199 _listIterator = _mapIterator.next().getValue().iterator(); 200 201 return _listIterator.next(); 202 } 203 204 public void remove() 205 { 206 throw new UnsupportedOperationException(); 207 } 208 } 209 } 155 210 }
Note:
See TracChangeset
for help on using the changeset viewer.