001    /*
002     *   Copyright (c) 2009 The JOMC Project
003     *   Copyright (c) 2005 Christian Schulte <cs@jomc.org>
004     *   All rights reserved.
005     *
006     *   Redistribution and use in source and binary forms, with or without
007     *   modification, are permitted provided that the following conditions
008     *   are met:
009     *
010     *     o Redistributions of source code must retain the above copyright
011     *       notice, this list of conditions and the following disclaimer.
012     *
013     *     o Redistributions in binary form must reproduce the above copyright
014     *       notice, this list of conditions and the following disclaimer in
015     *       the documentation and/or other materials provided with the
016     *       distribution.
017     *
018     *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
019     *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020     *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021     *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
022     *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023     *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024     *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025     *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026     *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
027     *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
028     *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029     *
030     *   $Id: ModelObjectValidationReport.java 891 2009-11-02 03:40:00Z schulte2005 $
031     *
032     */
033    package org.jomc.model;
034    
035    import java.io.Serializable;
036    import java.util.ArrayList;
037    import java.util.Collections;
038    import java.util.List;
039    import java.util.logging.Level;
040    import javax.xml.bind.JAXBElement;
041    
042    /**
043     * Validation report about a model object.
044     *
045     * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
046     * @version $Id: ModelObjectValidationReport.java 891 2009-11-02 03:40:00Z schulte2005 $
047     */
048    public class ModelObjectValidationReport implements Serializable
049    {
050    
051        /** Report detail. */
052        public static class Detail implements Serializable
053        {
054    
055            /** Serial version UID for backwards compatibility with 1.0.x object streams. */
056            private static final long serialVersionUID = 3602078739148823287L;
057    
058            /**
059             * The detail identifier.
060             * @serial
061             */
062            private String identifier;
063    
064            /**
065             * The detail level.
066             * @serial
067             */
068            private Level level;
069    
070            /**
071             * The detail message.
072             * @serial
073             */
074            private String message;
075    
076            /**
077             * The JAXB element this detail is associated with.
078             * @serial
079             */
080            private JAXBElement element;
081    
082            /**
083             * Creates a new {@code Detail} taking an identifier, a level and a message.
084             *
085             * @param identifier The detail identifier.
086             * @param level The detail level.
087             * @param message The detail message.
088             */
089            public Detail( final String identifier, final Level level, final String message )
090            {
091                this.identifier = identifier;
092                this.level = level;
093                this.message = message;
094            }
095    
096            /**
097             * Gets the identifier of this detail.
098             *
099             * @return The identifier of this detail or {@code null}.
100             */
101            public String getIdentifier()
102            {
103                return this.identifier;
104            }
105    
106            /**
107             * Gets the level of this detail.
108             *
109             * @return The level of this detail or {@code null}.
110             */
111            public Level getLevel()
112            {
113                return this.level;
114            }
115    
116            /**
117             * Gets the message of this detail.
118             *
119             * @return The message of this detail or {@code null}.
120             */
121            public String getMessage()
122            {
123                return this.message;
124            }
125    
126            /**
127             * Gets the JAXB element of this detail.
128             *
129             * @return The JAXB element of this detail or {@code null}.
130             */
131            public JAXBElement getElement()
132            {
133                return this.element;
134            }
135    
136            /**
137             * Sets the JAXB element of this detail.
138             *
139             * @param value The new JAXB element of this detail or {@code null}.
140             */
141            public void setElement( final JAXBElement value )
142            {
143                this.element = value;
144            }
145    
146            /**
147             * Creates and returns a string representation of the object.
148             *
149             * @return A string representation of the object.
150             */
151            private String toStringInternal()
152            {
153                return new StringBuilder().append( '{' ).
154                    append( "identifier=" ).append( this.getIdentifier() ).
155                    append( ", level=" ).append( this.getLevel().getLocalizedName() ).
156                    append( ", message=" ).append( this.getMessage() ).
157                    append( ", element=" ).append( this.getElement() ).append( '}' ).toString();
158    
159            }
160    
161            /**
162             * Creates and returns a string representation of the object.
163             *
164             * @return A string representation of the object.
165             */
166            @Override
167            public String toString()
168            {
169                return super.toString() + this.toStringInternal();
170            }
171    
172        }
173    
174        /** Serial version UID for backwards compatibility with 1.0.x object streams. */
175        private static final long serialVersionUID = 5347328444554122366L;
176    
177        /**
178         * The model object of the instance.
179         * @serial
180         */
181        private JAXBElement modelObject;
182    
183        /**
184         * Details of the instance.
185         * @serial
186         */
187        private List<Detail> details;
188    
189        /**
190         * Creates a new {@code ModelObjectValidationReport} instance taking a model object.
191         *
192         * @param modelObject The model object of the report.
193         */
194        public ModelObjectValidationReport( final JAXBElement modelObject )
195        {
196            this.modelObject = modelObject;
197        }
198    
199        /**
200         * Gets the model object of the instance.
201         *
202         * @return The model object of the instance.
203         */
204        public JAXBElement getModelObject()
205        {
206            return this.modelObject;
207        }
208    
209        /**
210         * Gets all details of the instance.
211         * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make
212         * to the returned list will be present inside the object. This is why there is no {@code set} method for the
213         * details property.</p>
214         *
215         *
216         * @return All details of the instance.
217         */
218        public List<Detail> getDetails()
219        {
220            if ( this.details == null )
221            {
222                this.details = new ArrayList<Detail>();
223            }
224    
225            return this.details;
226        }
227    
228        /**
229         * Gets all details of the instance matching a given identifier.
230         *
231         * @param identifier The identifier of the details to return or {@code null}.
232         *
233         * @return An unmodifiable list containing all details of the instance matching {@code identifier}.
234         */
235        public List<Detail> getDetails( final String identifier )
236        {
237            final List<Detail> list = new ArrayList( this.getDetails().size() );
238    
239            for ( Detail d : this.getDetails() )
240            {
241                if ( identifier == null && d.getIdentifier() == null )
242                {
243                    list.add( d );
244                }
245                if ( identifier != null && identifier.equals( d.getIdentifier() ) )
246                {
247                    list.add( d );
248                }
249            }
250    
251            return Collections.unmodifiableList( list );
252        }
253    
254        /**
255         * Gets a flag indicating if the model object of the instance is considered valid.
256         *
257         * @return {@code true} if the model object of the instance is considered valid; {@code false} if the model object
258         * of the instance is considered invalid.
259         */
260        public boolean isModelObjectValid()
261        {
262            for ( Detail d : this.getDetails() )
263            {
264                if ( d.getLevel() != null && d.getLevel().intValue() > Level.WARNING.intValue() )
265                {
266                    return false;
267                }
268            }
269    
270            return true;
271        }
272    
273    }