001    // SECTION-START[License Header]
002    // <editor-fold defaultstate="collapsed" desc=" Generated License ">
003    /*
004     *   Copyright (c) 2010 The JOMC Project
005     *   Copyright (c) 2005 Christian Schulte <schulte2005@users.sourceforge.net>
006     *   All rights reserved.
007     *
008     *   Redistribution and use in source and binary forms, with or without
009     *   modification, are permitted provided that the following conditions
010     *   are met:
011     *
012     *     o Redistributions of source code must retain the above copyright
013     *       notice, this list of conditions and the following disclaimer.
014     *
015     *     o Redistributions in binary form must reproduce the above copyright
016     *       notice, this list of conditions and the following disclaimer in
017     *       the documentation and/or other materials provided with the
018     *       distribution.
019     *
020     *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
021     *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022     *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023     *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
024     *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025     *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026     *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027     *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028     *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
029     *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
030     *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031     *
032     *   $Id: SdkModelProcessor.java 2234 2010-06-29 00:03:38Z schulte2005 $
033     *
034     */
035    // </editor-fold>
036    // SECTION-END
037    package org.jomc.sdk.model.modlet;
038    
039    import java.text.MessageFormat;
040    import java.util.ResourceBundle;
041    import java.util.logging.Level;
042    import org.jomc.model.Dependency;
043    import org.jomc.model.Implementation;
044    import org.jomc.model.Module;
045    import org.jomc.model.Modules;
046    import org.jomc.model.Properties;
047    import org.jomc.model.Property;
048    import org.jomc.model.Specification;
049    import org.jomc.model.modlet.ModelHelper;
050    import org.jomc.modlet.Model;
051    import org.jomc.modlet.ModelContext;
052    import org.jomc.modlet.ModelException;
053    import org.jomc.modlet.ModelProcessor;
054    
055    // SECTION-START[Documentation]
056    // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
057    /**
058     * SDK 'ModelProcessor' implementation.
059     *
060     * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.0
061     * @version $Id: SdkModelProcessor.java 2234 2010-06-29 00:03:38Z schulte2005 $
062     */
063    // </editor-fold>
064    // SECTION-END
065    // SECTION-START[Annotations]
066    // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
067    @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
068    // </editor-fold>
069    // SECTION-END
070    public final class SdkModelProcessor implements ModelProcessor
071    {
072        // SECTION-START[SdkModelProcessor]
073    
074        public Model processModel( final ModelContext context, final Model model ) throws ModelException
075        {
076            if ( context == null )
077            {
078                throw new NullPointerException( "context" );
079            }
080            if ( model == null )
081            {
082                throw new NullPointerException( "model" );
083            }
084    
085            Model processed = null;
086            Modules modules = ModelHelper.getModules( model );
087    
088            if ( modules != null )
089            {
090                if ( context.isLoggable( Level.FINE ) )
091                {
092                    context.log( Level.FINE, getMessage(
093                        "processingModel", this.getClass().getName(), model.getIdentifier() ), null );
094    
095                }
096    
097                processed = new Model( model );
098                modules = ModelHelper.getModules( processed );
099                this.substituteSystemProperties( modules );
100            }
101            else if ( context.isLoggable( Level.WARNING ) )
102            {
103                context.log( Level.WARNING, getMessage( "modulesNotFound", model.getIdentifier() ), null );
104            }
105    
106            return processed;
107        }
108    
109        private void substituteSystemProperties( final Modules modules )
110        {
111            for ( Module m : modules.getModule() )
112            {
113                this.substituteSystemProperties( m.getProperties() );
114    
115                if ( m.getSpecifications() != null )
116                {
117                    for ( Specification s : m.getSpecifications().getSpecification() )
118                    {
119                        this.substituteSystemProperties( s.getProperties() );
120                    }
121                }
122    
123                if ( m.getImplementations() != null )
124                {
125                    for ( Implementation i : m.getImplementations().getImplementation() )
126                    {
127                        this.substituteSystemProperties( i.getProperties() );
128    
129                        if ( i.getDependencies() != null )
130                        {
131                            for ( Dependency d : i.getDependencies().getDependency() )
132                            {
133                                this.substituteSystemProperties( d );
134                            }
135                        }
136                    }
137                }
138            }
139        }
140    
141        private void substituteSystemProperties( final Dependency dependency )
142        {
143            this.substituteSystemProperties( dependency.getProperties() );
144    
145            if ( dependency.getDependencies() != null )
146            {
147                for ( Dependency d : dependency.getDependencies().getDependency() )
148                {
149                    this.substituteSystemProperties( d );
150                }
151            }
152        }
153    
154        private void substituteSystemProperties( final Properties properties )
155        {
156            final String startingMarker =
157                System.getProperty( "org.jomc.sdk.model.modlet.SdkModelProcessor.systemPropertyStartingMarker", "@@" );
158    
159            final String endingMarker =
160                System.getProperty( "org.jomc.sdk.model.modlet.SdkModelProcessor.systemPropertyEndingMarker", "@@" );
161    
162            if ( properties != null )
163            {
164                for ( Property p : properties.getProperty() )
165                {
166                    if ( p.getValue() != null )
167                    {
168                        final StringBuilder b = new StringBuilder();
169                        final StringBuilder propertyName = new StringBuilder();
170                        boolean inPropertyName = false;
171    
172                        for ( int i = 0; i < p.getValue().length(); i++ )
173                        {
174                            if ( !inPropertyName )
175                            {
176                                if ( i + startingMarker.length() <= p.getValue().length()
177                                     && startingMarker.equals( p.getValue().substring( i, i + startingMarker.length() ) ) )
178                                {
179                                    propertyName.setLength( 0 );
180                                    propertyName.append( startingMarker );
181                                    i += startingMarker.length() - 1;
182                                    inPropertyName = true;
183                                    continue;
184                                }
185    
186                                b.append( p.getValue().charAt( i ) );
187                                continue;
188                            }
189    
190                            if ( inPropertyName )
191                            {
192                                if ( i + endingMarker.length() <= p.getValue().length()
193                                     && endingMarker.equals( p.getValue().substring( i, i + endingMarker.length() ) ) )
194                                {
195                                    b.append( System.getProperty( propertyName.substring( startingMarker.length() ),
196                                                                  propertyName + endingMarker ) );
197    
198                                    propertyName.setLength( 0 );
199                                    i += endingMarker.length() - 1;
200                                    inPropertyName = false;
201                                    continue;
202                                }
203    
204                                propertyName.append( p.getValue().charAt( i ) );
205                                continue;
206                            }
207                        }
208    
209                        if ( propertyName.length() > 0 )
210                        {
211                            b.append( propertyName );
212                        }
213    
214                        p.setValue( b.toString() );
215                    }
216                }
217            }
218        }
219    
220        private static String getMessage( final String key, final Object... arguments )
221        {
222            return MessageFormat.format( ResourceBundle.getBundle( SdkModelProcessor.class.getName().replace( '.', '/' ) ).
223                getString( key ), arguments );
224    
225        }
226    
227        // SECTION-END
228        // SECTION-START[Constructors]
229        // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
230    
231        /** Creates a new {@code SdkModelProcessor} instance. */
232        @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
233        public SdkModelProcessor()
234        {
235            // SECTION-START[Default Constructor]
236            super();
237            // SECTION-END
238        }
239        // </editor-fold>
240        // SECTION-END
241        // SECTION-START[Dependencies]
242        // SECTION-END
243        // SECTION-START[Properties]
244        // SECTION-END
245        // SECTION-START[Messages]
246        // SECTION-END
247    }