//----------------------------------------------------------------------------// // // // A c t i o n s // // // //----------------------------------------------------------------------------// // <editor-fold defaultstate="collapsed" desc="hdr"> // // Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. // // This software is released under the GNU General Public License. // // Goto http://kenai.com/projects/audiveris to report bugs or suggestions. // //----------------------------------------------------------------------------// // </editor-fold> package omr.action; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** * Class {@code Actions} handles all actions descriptors. * * @author Hervé Bitteur */ @XmlAccessorType(XmlAccessType.NONE) @XmlRootElement(name = "actions") public class Actions { //~ Static fields/initializers --------------------------------------------- /** Usual logger utility */ private static final Logger logger = LoggerFactory.getLogger(Actions.class); /** Context for JAXB unmarshalling */ private static volatile JAXBContext jaxbContext; /** The collection of all actions loaded so far */ private static final Set<ActionDescriptor> allDescriptors = new LinkedHashSet<>(); //~ Enumerations ----------------------------------------------------------- /** * Predefined list of domain names. * Through the action list files, the user will be able to add new domain * names. * This classification is mainly used to define the related pull-down menus. */ public static enum Domain { //~ Enumeration constant initializers ---------------------------------- /** Domain of file actions */ FILE, /** Domain of individual steps */ STEP, /** Domain of score actions */ SCORE, /** Domain of MIDI features */ MIDI, /** Domain of various view features */ VIEW, /** Domain of utilities */ TOOL, /** Domain of plugins */ PLUGIN, /** Domain of help information */ HELP; } //~ Instance fields -------------------------------------------------------- // /** Collection of descriptors loaded by unmarshalling one file. */ @XmlElement(name = "action") private List<ActionDescriptor> descriptors = new ArrayList<>(); //~ Constructors ----------------------------------------------------------- // //---------// // Actions // //---------// /** Not meant to be instantiated */ private Actions () { } //~ Methods ---------------------------------------------------------------- // //-------------------// // getAllDescriptors // //-------------------// /** * Report the collection of descriptors loaded so far. * @return all the loaded action descriptors */ public static Set<ActionDescriptor> getAllDescriptors () { return allDescriptors; } //----------------// // getDomainNames // //----------------// /** * Report the whole collection of domain names, starting with the * predefined ones. * @return the collection of domain names */ public static Set<String> getDomainNames () { Set<String> names = new LinkedHashSet<>(); // Predefined ones, except HELP for (Domain domain : Domain.values()) { if (domain != Domain.HELP) { names.add(domain.name()); } } // User-specified ones, except HELP for (ActionDescriptor desc : allDescriptors) { if (!desc.domain.equalsIgnoreCase(Domain.HELP.toString())) { names.add(desc.domain); } } // Add HELP as the very last one names.add(Domain.HELP.name()); return names; } //-------------// // getSections // //-------------// /** * Report the whole collection of sections, the predefined ones * and the added ones. * @return the collection of sections */ public static SortedSet<Integer> getSections () { SortedSet<Integer> sections = new TreeSet<>(); for (ActionDescriptor desc : allDescriptors) { sections.add(desc.section); } return sections; } //-----------------// // loadActionsFrom // //-----------------// /** * Unmarshal the provided XML stream to allocate the corresponding * collection of action descriptors. * * @param in the input stream that contains the collection of action * descriptors in XML format. The stream is not closed by this method * @throws javax.xml.bind.JAXBException */ public static void loadActionsFrom (InputStream in) throws JAXBException { if (jaxbContext == null) { jaxbContext = JAXBContext.newInstance(Actions.class); } Unmarshaller um = jaxbContext.createUnmarshaller(); Actions actions = (Actions) um.unmarshal(in); for (ActionDescriptor desc : actions.descriptors) { logger.debug("Descriptor unmarshalled {}", desc); } // Verify that all actions have a domain and a section assigned for (Iterator<ActionDescriptor> it = actions.descriptors.iterator(); it.hasNext();) { ActionDescriptor desc = it.next(); if (desc.domain == null) { logger.warn("No domain specified for {}", desc); it.remove(); continue; } if (desc.section == null) { logger.warn("No section specified for {}", desc); it.remove(); continue; } } allDescriptors.addAll(actions.descriptors); } }