001    /*
002     *   Copyright (C) Christian Schulte, 2005-206
003     *   All rights reserved.
004     *
005     *   Redistribution and use in source and binary forms, with or without
006     *   modification, are permitted provided that the following conditions
007     *   are met:
008     *
009     *     o Redistributions of source code must retain the above copyright
010     *       notice, this list of conditions and the following disclaimer.
011     *
012     *     o Redistributions in binary form must reproduce the above copyright
013     *       notice, this list of conditions and the following disclaimer in
014     *       the documentation and/or other materials provided with the
015     *       distribution.
016     *
017     *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
018     *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
019     *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
020     *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
021     *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
022     *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
023     *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
024     *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025     *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
026     *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027     *
028     *   $JOMC: ModelValidationReport.java 3838 2011-10-08 20:15:41Z schulte2005 $
029     *
030     */
031    package org.jomc.modlet;
032    
033    import java.io.Serializable;
034    import java.util.ArrayList;
035    import java.util.Collections;
036    import java.util.List;
037    import java.util.logging.Level;
038    import javax.xml.bind.JAXBElement;
039    
040    /**
041     * {@code Model} validation report.
042     *
043     * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
044     * @version $JOMC: ModelValidationReport.java 3838 2011-10-08 20:15:41Z schulte2005 $
045     */
046    public class ModelValidationReport implements Serializable
047    {
048    
049        /** Report detail. */
050        public static class Detail implements Serializable
051        {
052    
053            /** Serial version UID for backwards compatibility with 1.0.x object streams. */
054            private static final long serialVersionUID = -2466230076806042116L;
055    
056            /**
057             * The detail identifier.
058             * @serial
059             */
060            private String identifier;
061    
062            /**
063             * The detail level.
064             * @serial
065             */
066            private Level level;
067    
068            /**
069             * The detail message.
070             * @serial
071             */
072            private String message;
073    
074            /**
075             * The JAXB element this detail is associated with.
076             * @serial
077             */
078            private JAXBElement<?> element;
079    
080            /**
081             * Creates a new {@code Detail} taking an identifier, a level, a message and an element.
082             *
083             * @param identifier The detail identifier.
084             * @param level The detail level.
085             * @param message The detail message.
086             * @param element The detail element.
087             */
088            public Detail( final String identifier, final Level level, final String message, final JAXBElement<?> element )
089            {
090                this.identifier = identifier;
091                this.level = level;
092                this.message = message;
093                this.element = element;
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             * Creates and returns a string representation of the object.
138             *
139             * @return A string representation of the object.
140             */
141            private String toStringInternal()
142            {
143                return new StringBuilder( 200 ).append( '{' ).
144                    append( "identifier=" ).append( this.getIdentifier() ).
145                    append( ", level=" ).append( this.getLevel().getLocalizedName() ).
146                    append( ", message=" ).append( this.getMessage() ).
147                    append( ", element=" ).append( this.getElement() ).append( '}' ).toString();
148    
149            }
150    
151            /**
152             * Creates and returns a string representation of the object.
153             *
154             * @return A string representation of the object.
155             */
156            @Override
157            public String toString()
158            {
159                return super.toString() + this.toStringInternal();
160            }
161    
162        }
163    
164        /** Serial version UID for backwards compatibility with 1.0.x object streams. */
165        private static final long serialVersionUID = 6688024709865043122L;
166    
167        /**
168         * Details of the instance.
169         * @serial
170         */
171        private List<Detail> details;
172    
173        /** Creates a new {@code ModelValidationReport} instance. */
174        public ModelValidationReport()
175        {
176            super();
177        }
178    
179        /**
180         * Gets all details of the instance.
181         * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make
182         * to the returned list will be present inside the object. This is why there is no {@code set} method for the
183         * details property.</p>
184         *
185         * @return All details of the instance.
186         */
187        public List<Detail> getDetails()
188        {
189            if ( this.details == null )
190            {
191                this.details = new ArrayList<Detail>();
192            }
193    
194            return this.details;
195        }
196    
197        /**
198         * Gets all details of the instance matching a given identifier.
199         *
200         * @param identifier The identifier of the details to return or {@code null}.
201         *
202         * @return An unmodifiable list containing all details of the instance matching {@code identifier}.
203         */
204        public List<Detail> getDetails( final String identifier )
205        {
206            final List<Detail> list = new ArrayList<Detail>( this.getDetails().size() );
207    
208            for ( int i = this.getDetails().size() - 1; i >= 0; i-- )
209            {
210                final Detail d = this.getDetails().get( i );
211                if ( identifier == null && d.getIdentifier() == null )
212                {
213                    list.add( d );
214                }
215                if ( identifier != null && identifier.equals( d.getIdentifier() ) )
216                {
217                    list.add( d );
218                }
219            }
220    
221            return Collections.unmodifiableList( list );
222        }
223    
224        /**
225         * Gets a flag indicating model validity.
226         *
227         * @return {@code true}, if all details are set to a level lower or equal to {@code WARNING}; {@code false}, if at
228         * least one detail is set to a level higher than {@code WARNING}.
229         *
230         * @see #getDetails()
231         */
232        public boolean isModelValid()
233        {
234            for ( int i = this.getDetails().size() - 1; i >= 0; i-- )
235            {
236                final Detail d = this.getDetails().get( i );
237                if ( d.getLevel() != null && d.getLevel().intValue() > Level.WARNING.intValue() )
238                {
239                    return false;
240                }
241            }
242    
243            return true;
244        }
245    
246    }