
org.glassfish.hk2.xml.api.XmlRootHandle Maven / Gradle / Ivy
/* * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at * http://www.eclipse.org/legal/epl-2.0. * * This Source Code may also be made available under the following Secondary * Licenses when the conditions for such availability set forth in the * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, * version 2 with the GNU Classpath Exception, which is available at * https://www.gnu.org/software/classpath/license.html. * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ package org.glassfish.hk2.xml.api; import java.beans.VetoableChangeListener; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.util.List; import java.util.Map; /** * This represents XML data and a JavaBean tree * * @author jwells * */ public interface XmlRootHandle
* * @return The never null transaction object that must either be abandoned * or committed before the write lock on this bean tree is released * @throws IllegalStateException if this bean tree is not allowed to have * a transaction started on it */ public XmlHandleTransaction{ /** * Gets the root of the JavaBean tree * * @return The root of the JavaBean tree. Will * only return null if the tree has not yet * been created */ public T getRoot(); /** * Returns the root interface of this handle * * @return The root class or interface of this * handle. Will not return null */ public Class getRootClass(); /** * Represents the original URI from which this * tree was parsed (or null if this tree did not * come from a URI) * * @return The original URI from which this tree * was parsed, or null if this tree did not come * from a URI */ public URI getURI(); /** * Returns true if this handles root and children * are advertised in it service locator * * @return true if the root and children are * advertised in the associated service locator */ public boolean isAdvertisedInLocator(); /** * Returns true if this handles root and children * are advertised in the {@link org.glassfish.hk2.configuration.hub.api.Hub} * * @return true if the root and children are * advertised in the associated * {@link org.glassfish.hk2.configuration.hub.api.Hub} */ public boolean isAdvertisedInHub(); /** * This method returns a read-only copy of the existing * tree. Any method that would change anything in this * tree will fail. Methods that are customized will also * fail * * If representsDefaults is true then getters for unset * fields will return the default value. If representsDefaults * is false then getters for unset fields will return null * (or 0 (and false) for scalars). Setting representsDefault * to false is useful if this tree is to be used to marshall * back to XML, since JAXB will then not write the values back * out to the file * * @param representDefaults If true getters will return default values, * if false getters will return null (or zero/false for scalars) * @return A read-only copy of this xml tree or null if there is * no current root for this handle */ public T getReadOnlyRoot(boolean representDefaults); /** * Creates a copy of this tree that is not advertised. * Modifications can be made to this copy and then * merged back into the parent in a single transaction *
* There is no requirement to call {@link XmlRootCopy#merge()} * since the parent keeps no track of children. However, * the {@link XmlRootCopy#merge()} method will fail if * a modification has been made to the parent since the * time the copy was created * * @return A non-null copy of this root that can be modified * and then merged back in a single transaction */ public XmlRootCopy
getXmlRootCopy(); /** * This method overlays the current root and children with * the root and children from newRoot. newRoot must * have the same rootClass and must NOT be advertised * in either the locator or the hub. The system will * calculate the set of changes needed to convert this * root into the root from newRoot. * * All nodes that are at the same spot in the tree (have the same * xpath and same instance name) will not be modified, but will * instead have attributes changed. All nodes present in newRoot * but not in this root will be considered adds. All nodes * not present in newRoot but in this root will be considered deletes *
* The URI will not be modified by this call, nor will the * state of advertisement * * @param newRoot The non-null root that will be overlayed * onto this handle */ public void overlay(XmlRootHandle
newRoot); /** * If this handle does not already have a * root bean this method will add the one * given * * @param root The non-null instance of the * root type of this handle * @throws IllegalStateException if this handle * already has a root */ public void addRoot(T root); /** * This method can be used if the root of the * tree has no required fields, and is the * combination of {@link XmlService#createBean(Class)} * and {@link #addRoot(Object)}. This method * will throw an exception from the validator * (if validation is enabled) if the root type * has required fields or fails other validation */ public void addRoot(); /** * If this handle has a root this method * will delete it and all children, leaving * the root of this tree null * * @return The root that was deleted, or null * if the root was already null */ public T removeRoot(); /** * Adds a change listener to be invoked before any property is * set or a bean is added. The listener must be suitable for * storage in a HashSet. * * Rules for change listener: *
*
* * @param listeners non-null listeners to be called whenever * a property is changed in any bean in this root. Must be * suitable for storage in a HashSet */ public void addChangeListener(VetoableChangeListener... listeners); /** * Removes a change listener. The listener must be suitable for * lookup in a HashSet * * @param listener non-null listeners to be removed. Must be * suitable for lookup in a HashSet */ public void removeChangeListener(VetoableChangeListener... listeners); /** * Gets the current list of change listeners * * @return The non-null but possibly empty list of change * listeners to be called when a bean is added, removed * or modified */ public List- Adds of beans with children will get called back for each child and sub-child added
*- Add listener callbacks will happen parent first but children at the same level are handled in any order
*- When adding a bean the following events will be generated:
*
*- An event with an empty string as the propertyName, oldValue null, newValue and source set to the added bean
*- An event for the parent being added to with propertyName, oldValue the old list or array or direct child, new value the new list or array * or direct child
*- Remove listener callbacks will happen child first but children at the same level are handled in any order
*- When removing a bean the following events will be generated:
*
*- An event with an empty string as the propertyName, oldValue the removed bean, newValue null, and source set to the removed bean
*- An event for the parent being removed from with propertyName, oldValue the old list or array or direct child, new value the new list or array * or null for the direct child
*- Listeners are run in the order in which they are added
*- If a listener throws a PropertyVetoException subsequent listeners are NOT called and the update will not happen
*- If a listener throws any exception other than PropertyVertoException subsequent listeners WILL be called and the update will not happen
*- If any exceptions happen in any listeners they will end up all being reported in a MultiException
*getChangeListeners(); /** * This method will lock the bean tree represented by * this XmlRootHandle and start a transaction. Any changes * made while this transaction is in-flight will not be * visible to any other thread until this transaction is * committed. This transaction MUST be committed or abandoned * before any other thread can get access to any beans in * this tree. * * In particular, the code using this transaction should logically * behave like the following code: *
* XmlHandleTransactiontransaction = root.lockForTransaction(); * try { * // Do many many edits all at once * } * finally { * transaction.commit(); * } * lockForTransaction() throws IllegalStateException; /** * Does javax validation on the root bean from the root. This will * cause every change hereafter to be validated * * @throws ConstraintViolationException */ public void startValidating(); /** * Stops this root handle from doing javax validation * on modifications */ public void stopValidating(); /** * True if this handle is currently validating * changes */ public boolean isValidating(); /** * Will marshal this tree into the given stream. Will hold the read * lock of this tree while it does so that the tree cannot change * underneath while it is being written out. It will use a basic * indentation and new-line scheme * * @param outputStream A non-closed output stream. This method will * not close the output stream * @throws IOException On any exception that might happen */ public void marshal(OutputStream outputStream) throws IOException; /** * Will marshal this tree into the given stream. Will hold the read * lock of this tree while it does so that the tree cannot change * underneath while it is being written out. It will use a basic * indentation and new-line scheme * * @param outputStream A non-closed output stream. This method will * not close the output stream * @param options optional (possibly null) options from the caller * @throws IOException On any exception that might happen */ public void marshal(OutputStream outputStream, Map options) throws IOException; }