All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.tidalwave.metadata.Metadata Maven / Gradle / Ivy

/*******************************************************************************
 *
 * blueMarine - open source photo workflow
 * =======================================
 *
 * Copyright (C) 2003-2009 by Fabrizio Giudici
 * Project home page: http://bluemarine.tidalwave.it
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 *
 *******************************************************************************
 *
 * $Id: Metadata.java,v 64ddf5de96db 2009/11/06 20:43:18 fabrizio $
 *
 ******************************************************************************/
package it.tidalwave.metadata;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
import org.openide.loaders.DataObject;

/*******************************************************************************
 *
 * This class represents a bag of metadata items for a {@link DataObject}. 
 * Instances of Metadata can be achieved by asking for them to the 
 * object {@link Lookup} as in the following example:
 * 
 * 
 * DataObject dataObject = ...;
 * Metadata metadata = dataObject.getLookup().lookup(Metadata.class);
 * 
* * For each dataObject it is guaranteed that a non-null reference * to an unique instance of Metadata is returned (it will be empty * if no metadata is found). Single items can be then retrieved by calling the * {@link Metadata#findOrCreateItem(java.lang.Class, it.tidalwave.metadata.Metadata.FindOption[]) * findOrCreateItem()} method: * *
 * MetadataItemHolder<EXIF> exifHolder = metadata.findOrCreateItem(EXIF.class);
 * MetadataItemHolder<IPTC> iptcHolder = metadata.findOrCreateItem(IPTC.class);
 * EXIF exif = exifHolder.get();
 * IPTC iptc = iptcHolder.get();
 * 
* * or, more quickly: * *
 * EXIF exif = metadata.findOrCreateItem(EXIF.class).get();
 * IPTC iptc = metadata.findOrCreateItem(IPTC.class).get();
 * 
* * The {@link MetadataItemHolder} class is just a wrapper holding the real item and * providing some additional information: * *
 * MetadataItemHolder<EXIF> exifHolder = metadata.findOrCreateItem(EXIF.class);
 * boolean available = exifHolder.isAvailable();
 * Date lmt = exifHolder.getLatestModificationTime();
 * String sourceName = exifHolder.getSourceName();
 * String origin = exifHolder.getOrigin();
 * 
* * It is guaranteed that non null objects are always returned by * findOrCreateItem(); you * must check the {@link MetadataItemHolder#isAvailable()} property to understand * whether the object is empty or not.. * * Multiple calls with the same class specifier are guaranteed to return the * same instance of MetadataItemHolder, which - in turn - will hold * the same instance of the bean. * * Each object returned by the MetadataItemHolder is guaranteed to * implement the full Java Bean specifications (events, listeners, etc.). * * Note that this happens even if the original class (in the above example * doesn't support the contract; in this case a dynamically enhanced object is * returned, and it is guaranteed to implement the JavaBean * interface: * *
 * MyItem myItem = metadata.findOrCreateItem(MyItem.class).get();
 * ((JavaBean)myItem).addPropertyChangeListener(...);
 *  
* * As an alternate approach, you can use reflection to find and invoke methods. * * @author Fabrizio Giudici * @version $Id: Metadata.java,v 64ddf5de96db 2009/11/06 20:43:18 fabrizio $ * ******************************************************************************/ public interface Metadata { /*************************************************************************** * * Interface which tags all possible options for the methods * {@link #findOrCreateItem(Class, FindOption[])} and * {@link #findOrCreateItems(Class, FindOption[])}. Refer to the documentation of * implementing classes for further information. * **************************************************************************/ public static interface FindOption { } /******************************************************************************************************************* * * Interface which tags all possible options for the method * {@link #storeItem(it.tidalwave.metadata.MetadataItemHolder, it.tidalwave.metadata.Metadata.StoreOption[])}. * Refer to the documentation of implementing classes for further information. * ******************************************************************************************************************/ public static interface StoreOption { } /*************************************************************************** * * This enumeration contains items to identify the metadata source and * sink types. * **************************************************************************/ public static enum StorageType implements FindOption, StoreOption { /** Matches any kind of source/sink. */ ANY_TYPE { public boolean includes (@Nonnull final StorageType sourceType) { return true; } }, /** Matches only internal sources/sinks, typically a dedicated persistence facility such as a database. */ INTERNAL { public boolean includes (@Nonnull final StorageType sourceType) { return sourceType == INTERNAL; } }, /** Matches only external sources/sinks, such as files (images or sidecar files). */ EXTERNAL { public boolean includes (@Nonnull final StorageType sourceType) { return sourceType == EXTERNAL; } }, NONE { public boolean includes (@Nonnull final StorageType sourceType) { return false; } }; public static final StorageType DEFAULT = INTERNAL; public abstract boolean includes (@Nonnull final StorageType sourceType); } /*************************************************************************** * * This enumeration contains items to choose which policy to use when * storing items. * **************************************************************************/ public static enum ReplaceOption implements Metadata.StoreOption { /** Means that any copy of the same metadata item (same type and origin) should not be dropped during store. */ DONT_REPLACE, /** Means that any copy of the same metadata item (same type and origin) must be dropped during store. */ REPLACE } /*************************************************************************** * * An option to tell the name of the origin of a datum to store. * **************************************************************************/ public static class OriginFilter implements StoreOption { @Nonnull private final List names; public OriginFilter (@Nonnull final String ... names) { this.names = Arrays.asList(names); } public OriginFilter (@Nonnull final Collection names) { this.names = new ArrayList(names); } public boolean matches (@Nonnull final String name) { return names.contains(name); } @Nonnull public Set getNames() { return new HashSet(names); } @Override @Nonnull public String toString() { return String.format("OriginFilter%s", names); } public static final OriginFilter ANY_ORIGIN = new OriginFilter() { @Override public final boolean matches (@Nonnull final String name) { return true; } @Override @Nonnull public Set getNames() { throw new RuntimeException("Don't call me"); } @Override @Nonnull public String toString() { return "OriginFilter[ANY_ORIGIN]"; } }; } /*************************************************************************** * * An option specifying a set of names for sinks. Only the sinks matching * the given names will be used. ANY_NAME matches all names. * **************************************************************************/ public static class NameFilter implements StoreOption { @Nonnull private final List names; public NameFilter (@Nonnull final String ... names) { this.names = Arrays.asList(names); } public NameFilter (@Nonnull final Collection names) { this.names = new ArrayList(names); } public boolean matches (@Nonnull final String name) { return names.contains(name); } @Override @Nonnull public String toString() { return String.format("NameFilter%s", names); } public static final NameFilter ANY_NAME = new NameFilter() { @Override public final boolean matches (@Nonnull final String name) { return true; } @Override @Nonnull public String toString() { return "NameFilter[ANY_NAME]"; } }; } /*************************************************************************** * * Returns all the supported item classes. * * @return the supported item classes * **************************************************************************/ @Nonnull public Set> getItemClasses(); /*************************************************************************** * * Probes the availability of the given metadata item. This method returns * true if the requested item has been already loaded in memory, * false if it hasn't and a (potentially time-expensive) search * is needed. * * @param metadataItemClass the type of the item * @param options the options (see {@link FindOption}) * @return true if the item is available * @throws NoSuchMetadataTypeException if the item type is not supported * **************************************************************************/ public boolean isItemAvailable (@Nonnull Class metadataItemClass, @Nonnull FindOption ... options) throws NoSuchMetadataTypeException; /*************************************************************************** * * Finds a metadata item given its class or creates it if none is found. * Items are lazily loaded the first time they are asked for. It is * guaranteed that the same instance will be always returned for a given * metadataItemClass. * If metadataItemClass is not valid (that is, is not one of * the supported classes, see {@link #getItemClasses()}), a * {@link NoSuchMetadataTypeException} is thrown. * For further information, see the comments about the {@link Metadata} class. * If you don't want to risk blocking on this method becase the requested item * has not been loaded yet, consider probing its availability by calling * {@link #isItemAvailable(Class, it.tidalwave.metadata.Metadata.FindOption[])}. * If the method returns false, you might want to call * findOrCreateItem() in a background thread. * * @param metadataItemClass the type of the item * @param options the options (see {@link FindOption}) * @return the item * @throws NoSuchMetadataTypeException if the item type is not supported * **************************************************************************/ @Nonnull public MetadataItemHolder findOrCreateItem (@Nonnull Class metadataItemClass, @Nonnull FindOption ... options) throws NoSuchMetadataTypeException; /*************************************************************************** * * Finds multiple metadata item given their class or creates one if none is * found. * Items are returned sorted by descending last modification time. * If metadataItemClass is not valid (that is, is not one of * the provided classes, see {@link #getItemClasses()}), a * {@link NoSuchMetadataTypeException} is thrown. Please see * {@link #findOrCreateItem(java.lang.Class, it.tidalwave.metadata.Metadata.FindOption[])} for further information. * * @param metadataItemClass the type of the item * @param options the options (see {@link FindOption}) * @return the items * @throws NoSuchMetadataTypeException if the item type is not supported * **************************************************************************/ @Nonnull public MetadataItemHolderList findOrCreateItems (@Nonnull Class metadataItemClass, @Nonnull FindOption ... options) throws NoSuchMetadataTypeException; /*************************************************************************** * * Stores an item into the available sinks (eventually filtered by the * options). * If item is not valid (that is, is not one of * the supported classes, see {@link #getItemClasses()}), a * {@link NoSuchMetadataTypeException} is thrown. * * @param holder the item to store * @param options the options (see {@link StoreOption}) * @return the number of successful stores * @throws NoSuchMetadataTypeException if the item type is not supported * **************************************************************************/ public int storeItem (@Nonnull MetadataItemHolder holder, @Nonnull StoreOption ... options) throws NoSuchMetadataTypeException; /*************************************************************************** * * Returns the bound {@link DataObject}. * * @return the bound object * **************************************************************************/ @Nonnull public DataObject getDataObject(); /*************************************************************************** * * Returns the latest modification time of this object. This property will * be updated whenever a contained item is updated. * * @return the latest modification time * **************************************************************************/ @Nonnull public Date getLatestModificationTime(); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy