001/* 002 * jDTAUS Core Resource Mojo 003 * Copyright (C) 2005 Christian Schulte 004 * <cs@schulte.it> 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License, or any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 019 * 020 */ 021package org.jdtaus.mojo.resource.model; 022 023import java.io.File; 024import java.io.IOException; 025import java.util.HashMap; 026import java.util.Iterator; 027import java.util.Map; 028import java.util.Properties; 029import javax.xml.bind.JAXBContext; 030import javax.xml.bind.JAXBException; 031import javax.xml.bind.Unmarshaller; 032import org.xml.sax.SAXException; 033 034/** 035 * Manages the {@code http://jdtaus.org/core/model/container} model. 036 * 037 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 038 * @version $JDTAUS: ModelManager.java 8641 2012-09-27 06:45:17Z schulte $ 039 * @plexus.component role="org.jdtaus.mojo.resource.model.ModelManager" 040 * role-hint="default" 041 */ 042public class ModelManager 043{ 044 045 /** 046 * Unmarshals a given module descriptor. 047 * 048 * @param moduleDescriptor module descriptor to unmarshall. 049 * 050 * @return the content tree unmarshalled from {@code moduleDescriptor}. 051 * 052 * @throws NullPointerException if {@code moduleDescriptor} is {@code null}. 053 * @throws JAXBException if unmarshalling fails. 054 * @throws SAXException if parsing fails. 055 * @throws IOException if reading fails. 056 */ 057 public Module getModule( final File moduleDescriptor ) 058 throws JAXBException, SAXException, IOException 059 { 060 Module module = null; 061 final JAXBContext ctx = JAXBContext.newInstance( 062 "org.jdtaus.mojo.resource.model" ); 063 064 final Unmarshaller unmarshaller = ctx.createUnmarshaller(); 065 final Object contentTree = unmarshaller.unmarshal( moduleDescriptor ); 066 if ( contentTree instanceof Module ) 067 { 068 module = (Module) contentTree; 069 } 070 071 return module; 072 } 073 074 /** 075 * Gets a message. 076 * 077 * @param module the module to search. 078 * @param messageName the name of the message to search. 079 * 080 * @return the message with name {@code name} from {@code module} or 081 * {@code null} if no message exists. 082 * 083 * @throws NullPointerException if {@code module} or {@code messageName} is 084 * {@code null}. 085 */ 086 public Message getMessage( final Module module, 087 final String messageName ) 088 { 089 if ( module == null ) 090 { 091 throw new NullPointerException( "module" ); 092 } 093 if ( messageName == null ) 094 { 095 throw new NullPointerException( "messageName" ); 096 } 097 098 Message message = null; 099 100 if ( module.getMessages() != null ) 101 { 102 for ( Iterator it = module.getMessages().getMessage().iterator(); 103 it.hasNext(); ) 104 { 105 final Message current = (Message) it.next(); 106 if ( current.getName().equals( messageName ) ) 107 { 108 message = current; 109 break; 110 } 111 } 112 } 113 114 return message; 115 } 116 117 /** 118 * Computes the hashcode of an implementation bundle. 119 * 120 * @param module the module containing {@code implementation}. 121 * @param implementation the implementation to compute the bundle hashcode 122 * of. 123 * 124 * @return the bundle hashcode of {@code implementation}. 125 * 126 * @throws NullPointerException if {@code module} or {@code implementation} 127 * is {@code null}. 128 */ 129 public int getHashCode( final Module module, 130 final Implementation implementation ) 131 { 132 if ( module == null ) 133 { 134 throw new NullPointerException( "module" ); 135 } 136 if ( implementation == null ) 137 { 138 throw new NullPointerException( "implementation" ); 139 } 140 141 int bundleHash = 23; 142 143 if ( implementation.getMessages() != null ) 144 { 145 for ( Iterator it = implementation.getMessages().getMessage(). 146 iterator(); it.hasNext(); ) 147 { 148 final Message message = (Message) it.next(); 149 bundleHash = 37 * bundleHash + message.getName().hashCode(); 150 for ( Iterator t = message.getTemplate().getText().iterator(); 151 t.hasNext(); ) 152 { 153 final Text text = (Text) t.next(); 154 bundleHash = 37 * bundleHash + text.getLanguage().hashCode(); 155 bundleHash = 37 * bundleHash + text.getValue().hashCode(); 156 } 157 158 if ( message.getArguments() != null ) 159 { 160 for ( Iterator a = message.getArguments().getArgument(). 161 iterator(); a.hasNext(); ) 162 { 163 final Argument argument = (Argument) a.next(); 164 bundleHash = 37 * bundleHash + argument.getName(). 165 hashCode(); 166 167 bundleHash = 37 * bundleHash + argument.getType(). 168 toString().hashCode(); 169 170 } 171 } 172 } 173 174 for ( Iterator it = implementation.getMessages().getReference(). 175 iterator(); it.hasNext(); ) 176 { 177 final MessageReference messageReference = 178 (MessageReference) it.next(); 179 180 final Message message = 181 this.getMessage( module, messageReference.getName() ); 182 183 for ( Iterator t = message.getTemplate().getText().iterator(); 184 t.hasNext(); ) 185 { 186 final Text text = (Text) t.next(); 187 bundleHash = 37 * bundleHash + text.getLanguage().hashCode(); 188 bundleHash = 37 * bundleHash + text.getValue().hashCode(); 189 } 190 191 if ( message.getArguments() != null ) 192 { 193 for ( Iterator a = message.getArguments().getArgument(). 194 iterator(); a.hasNext(); ) 195 { 196 final Argument argument = (Argument) a.next(); 197 bundleHash = 37 * bundleHash + argument.getName(). 198 hashCode(); 199 200 bundleHash = 37 * bundleHash + argument.getType(). 201 toString().hashCode(); 202 203 } 204 } 205 } 206 } 207 208 return bundleHash; 209 } 210 211 /** 212 * Builds a mapping of language codes to {@code Properties} instances 213 * holding the messages for the language. 214 * 215 * @param module the module containing {@code implementation}. 216 * @param implementation the implementation to get the properties for. 217 * 218 * @return mapping of language codes to {@code Properties} instances 219 * holding the messages for the language. 220 * 221 * @throws NullPointerException if {@code module} or {@code implementation} 222 * is {@code null}. 223 */ 224 public Map/*<String,Properties>*/ getBundleProperties( 225 final Module module, final Implementation implementation ) 226 { 227 if ( module == null ) 228 { 229 throw new NullPointerException( "module" ); 230 } 231 if ( implementation == null ) 232 { 233 throw new NullPointerException( "implementation" ); 234 } 235 236 final Map properties = new HashMap( 10 ); 237 238 if ( implementation.getMessages() != null ) 239 { 240 for ( Iterator it = implementation.getMessages().getMessage(). 241 iterator(); it.hasNext(); ) 242 { 243 final Message message = (Message) it.next(); 244 for ( Iterator t = message.getTemplate().getText().iterator(); 245 t.hasNext(); ) 246 { 247 final Text text = (Text) t.next(); 248 final String language = text.getLanguage().toLowerCase(); 249 250 Properties bundleProperties = 251 (Properties) properties.get( language ); 252 253 if ( bundleProperties == null ) 254 { 255 bundleProperties = new Properties(); 256 properties.put( language, bundleProperties ); 257 } 258 259 bundleProperties.setProperty( message.getName(), 260 text.getValue() ); 261 262 } 263 } 264 265 for ( Iterator it = implementation.getMessages().getReference(). 266 iterator(); it.hasNext(); ) 267 { 268 final MessageReference messageReference = 269 (MessageReference) it.next(); 270 271 final Message message = 272 this.getMessage( module, messageReference.getName() ); 273 274 for ( Iterator t = message.getTemplate().getText().iterator(); 275 t.hasNext(); ) 276 { 277 final Text text = (Text) t.next(); 278 final String language = text.getLanguage().toLowerCase(); 279 280 Properties bundleProperties = 281 (Properties) properties.get( language ); 282 283 if ( bundleProperties == null ) 284 { 285 bundleProperties = new Properties(); 286 properties.put( language, bundleProperties ); 287 } 288 289 bundleProperties.setProperty( message.getName(), 290 text.getValue() ); 291 292 } 293 } 294 } 295 296 return properties; 297 } 298 299 /** 300 * Gets the java package name of an implementation. 301 * 302 * @param implementation the implementation to get the java package name of. 303 * 304 * @return the java package name of {@code implementation}. 305 * 306 * @throws NullPointerException if {@code implementation} is {@code null}. 307 */ 308 public String getJavaPackageName( final Implementation implementation ) 309 { 310 if ( implementation == null ) 311 { 312 throw new NullPointerException( "implementation" ); 313 } 314 315 return implementation.getIdentifier(). 316 substring( 0, implementation.getIdentifier().lastIndexOf( '.' ) ); 317 318 } 319 320 /** 321 * Gets the java type name of an implementation. 322 * 323 * @param implementation the implementation to get the java type name of. 324 * 325 * @return the java type name of {@code implementation}. 326 * 327 * @throws NullPointerException if {@code implementation} is {@code null}. 328 */ 329 public String getJavaTypeName( final Implementation implementation ) 330 { 331 if ( implementation == null ) 332 { 333 throw new NullPointerException( "implementation" ); 334 } 335 336 return implementation.getIdentifier(). 337 substring( implementation.getIdentifier().lastIndexOf( '.' ) + 1 ) + 338 "Bundle"; 339 340 } 341 342 /** 343 * Formats a text to a javadoc comment. 344 * 345 * @param text the text to nformat to a javadoc comment. 346 * 347 * @return {@code text} formatted as a javadoc comment. 348 * 349 * @throws NullPointerException if {@code text} is {@code null}. 350 */ 351 public String getJavadocComment( final Text text ) 352 { 353 if ( text == null ) 354 { 355 throw new NullPointerException( "text" ); 356 } 357 358 String normalized = text.getValue(); 359 normalized = normalized.replaceAll( "\\/\\*\\*", "/*" ); 360 normalized = normalized.replaceAll( "\\*/", "/" ); 361 normalized = normalized.replaceAll( "\n", "\n *" ); 362 return normalized; 363 } 364 365 /** 366 * Gets the method name of a java accessor method for a given message. 367 * 368 * @param message the message to return the accessor method name for. 369 * 370 * @throws NullPointerException if {@code text} is {@code null}. 371 */ 372 public String getJavaAccessorMethodName( final Message message ) 373 { 374 if ( message == null ) 375 { 376 throw new NullPointerException( "message" ); 377 } 378 379 final char[] c = message.getName().toCharArray(); 380 c[0] = Character.toUpperCase( c[0] ); 381 382 return new StringBuffer( 255 ).append( "get" ). 383 append( String.valueOf( c ) ). 384 append( "Message" ).toString(); 385 386 } 387 388 /** 389 * Gets the java classpath location of an implementation bundle. 390 * 391 * @return implementation the implementation to return the bundle's java 392 * classpath location of. 393 * 394 * @return the java classpath location of the bundle of 395 * {@code implementation}. 396 * 397 * @throws NullPointerException if {@code implementation} is {@code null}. 398 */ 399 public String getJavaClasspathLocation( final Implementation implementation ) 400 { 401 if ( implementation == null ) 402 { 403 throw new NullPointerException( "implementation" ); 404 } 405 406 return ( this.getJavaPackageName( implementation ) + '.' + 407 this.getJavaTypeName( implementation ) ).replace( '.', '/' ); 408 409 } 410 411}