1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 package com.sun.star.filter.config.tools.merge; 24 25 //_______________________________________________ 26 27 import java.lang.*; 28 import java.util.*; 29 import java.io.*; 30 import com.sun.star.filter.config.tools.utils.*; 31 32 //_______________________________________________ 33 34 /** can merge different xml fragments together. 35 * 36 * 37 */ 38 public class Merger 39 { 40 //___________________________________________ 41 // const 42 43 private static final java.lang.String PROP_XMLVERSION = "xmlversion" ; // <= global cfg file 44 private static final java.lang.String PROP_XMLENCODING = "xmlencoding" ; // <= global cfg file 45 private static final java.lang.String PROP_XMLPATH = "xmlpath" ; // <= global cfg file 46 private static final java.lang.String PROP_XMLPACKAGE = "xmlpackage" ; // <= global cfg file 47 48 private static final java.lang.String PROP_SETNAME_TYPES = "setname_types" ; // <= global cfg file 49 private static final java.lang.String PROP_SETNAME_FILTERS = "setname_filters" ; // <= global cfg file 50 private static final java.lang.String PROP_SETNAME_LOADERS = "setname_frameloaders" ; // <= global cfg file 51 private static final java.lang.String PROP_SETNAME_HANDLERS = "setname_contenthandlers" ; // <= global cfg file 52 53 private static final java.lang.String PROP_SUBDIR_TYPES = "subdir_types" ; // <= global cfg file 54 private static final java.lang.String PROP_SUBDIR_FILTERS = "subdir_filters" ; // <= global cfg file 55 private static final java.lang.String PROP_SUBDIR_LOADERS = "subdir_frameloaders" ; // <= global cfg file 56 private static final java.lang.String PROP_SUBDIR_HANDLERS = "subdir_contenthandlers" ; // <= global cfg file 57 58 private static final java.lang.String PROP_EXTENSION_XCU = "extension_xcu" ; // <= global cfg file 59 private static final java.lang.String PROP_EXTENSION_PKG = "extension_pkg" ; // <= global cfg file 60 61 private static final java.lang.String PROP_DELIMITER = "delimiter" ; // <= global cfg file 62 private static final java.lang.String PROP_TRIM = "trim" ; // <= global cfg file 63 private static final java.lang.String PROP_DECODE = "decode" ; // <= global cfg file 64 65 private static final java.lang.String PROP_FRAGMENTSDIR = "fragmentsdir" ; // <= cmdline 66 private static final java.lang.String PROP_TEMPDIR = "tempdir" ; // <= cmdline 67 private static final java.lang.String PROP_OUTDIR = "outdir" ; // <= cmdline 68 private static final java.lang.String PROP_PKG = "pkg" ; // <= cmdline 69 private static final java.lang.String PROP_DEBUG = "debug" ; // <= cmdline 70 71 private static final java.lang.String PROP_TCFG = "tcfg" ; // <= cmdline 72 private static final java.lang.String PROP_FCFG = "fcfg" ; // <= cmdline 73 private static final java.lang.String PROP_LCFG = "lcfg" ; // <= cmdline 74 private static final java.lang.String PROP_CCFG = "ccfg" ; // <= cmdline 75 private static final java.lang.String PROP_LANGUAGEPACK = "languagepack" ; // <= cmdline 76 77 private static final java.lang.String PROP_ITEMS = "items" ; // <= pkg cfg files! 78 79 //___________________________________________ 80 // member 81 82 //------------------------------------------- 83 /** TODO */ 84 private ConfigHelper m_aCfg; 85 86 //------------------------------------------- 87 /** TODO */ 88 private Logger m_aLog; 89 90 //------------------------------------------- 91 /** TODO */ 92 private java.io.File m_aFragmentsDir; 93 94 //------------------------------------------- 95 /** TODO */ 96 private java.io.File m_aTempDir; 97 98 //------------------------------------------- 99 /** TODO */ 100 private java.io.File m_aOutDir; 101 102 //------------------------------------------- 103 /** TODO */ 104 private java.util.Vector m_lTypes; 105 private java.util.Vector m_lFilters; 106 private java.util.Vector m_lLoaders; 107 private java.util.Vector m_lHandlers; 108 109 //___________________________________________ 110 // interface 111 112 //------------------------------------------- 113 /** initialize a new instance of this class and 114 * try to get all needed resources from the config module. 115 * 116 * @param aCfg 117 * provides access to all values of the global 118 * config file and to the command line. 119 * 120 * @param aLog 121 * can be used to print out log informations. 122 */ Merger(ConfigHelper aCfg, Logger aLog)123 public Merger(ConfigHelper aCfg, 124 Logger aLog) 125 throws java.lang.Exception 126 { 127 m_aCfg = aCfg; 128 m_aLog = aLog; 129 130 m_aFragmentsDir = new java.io.File(m_aCfg.getString(PROP_FRAGMENTSDIR)); 131 m_aTempDir = new java.io.File(m_aCfg.getString(PROP_TEMPDIR )); 132 // m_aOutDir = new java.io.File(m_aCfg.getString(PROP_OUTDIR )); 133 134 java.lang.String sDelimiter = m_aCfg.getString(PROP_DELIMITER); 135 boolean bTrim = m_aCfg.getBoolean(PROP_TRIM); 136 boolean bDecode = m_aCfg.getBoolean(PROP_DECODE); 137 138 try 139 { 140 ConfigHelper aFcfg = new ConfigHelper(m_aCfg.getString(PROP_TCFG), null); 141 m_lTypes = aFcfg.getStringList(PROP_ITEMS, sDelimiter, bTrim, bDecode); 142 } 143 catch(java.util.NoSuchElementException ex1) 144 { 145 m_lTypes = new java.util.Vector(); 146 //m_aLog.setWarning("Fragment list of types is missing. Parameter \"items\" seems to be invalid."); 147 } 148 149 try 150 { 151 ConfigHelper aFcfg = new ConfigHelper(m_aCfg.getString(PROP_FCFG), null); 152 m_lFilters = aFcfg.getStringList(PROP_ITEMS, sDelimiter, bTrim, bDecode); 153 } 154 catch(java.util.NoSuchElementException ex1) 155 { 156 m_lFilters = new java.util.Vector(); 157 //m_aLog.setWarning("Fragment list of filters is missing. Parameter \"items\" seems to be invalid."); 158 } 159 160 try 161 { 162 ConfigHelper aFcfg = new ConfigHelper(m_aCfg.getString(PROP_LCFG), null); 163 m_lLoaders = aFcfg.getStringList(PROP_ITEMS, sDelimiter, bTrim, bDecode); 164 } 165 catch(java.util.NoSuchElementException ex1) 166 { 167 m_lLoaders = new java.util.Vector(); 168 //m_aLog.setWarning("Fragment list of frame loader objects is missing. Parameter \"items\" seems to be invalid."); 169 } 170 171 try 172 { 173 ConfigHelper aFcfg = new ConfigHelper(m_aCfg.getString(PROP_CCFG), null); 174 m_lHandlers = aFcfg.getStringList(PROP_ITEMS, sDelimiter, bTrim, bDecode); 175 } 176 catch(java.util.NoSuchElementException ex1) 177 { 178 m_lHandlers = new java.util.Vector(); 179 //m_aLog.setWarning("Fragment list of content handler objects is missing. Parameter \"items\" seems to be invalid."); 180 } 181 } 182 183 //------------------------------------------- 184 /** TODO */ merge()185 public synchronized void merge() 186 throws java.lang.Exception 187 { 188 java.lang.StringBuffer sBuffer = new java.lang.StringBuffer(1000000); 189 java.lang.String sPackage = m_aCfg.getString(PROP_PKG); 190 191 m_aLog.setGlobalInfo("create package \""+sPackage+"\" ..."); 192 m_aLog.setDetailedInfo("generate package header ... "); 193 194 sBuffer.append( 195 XMLHelper.generateHeader( 196 m_aCfg.getString (PROP_XMLVERSION ), 197 m_aCfg.getString (PROP_XMLENCODING ), 198 m_aCfg.getString (PROP_XMLPATH ), 199 m_aCfg.getString (PROP_XMLPACKAGE ), 200 m_aCfg.getBoolean(PROP_LANGUAGEPACK, false))); 201 202 // counts all transfered fragments 203 // Can be used later to decide, if a generated package file 204 // contains "nothing"! 205 int nItemCount = 0; 206 207 for (int i=0; i<4; ++i) 208 { 209 java.lang.String sSetName = null; 210 java.lang.String sSubDir = null; 211 java.util.Vector lFragments = null; 212 213 try 214 { 215 switch(i) 216 { 217 case 0: // types 218 { 219 m_aLog.setDetailedInfo("generate set for types ... "); 220 sSetName = m_aCfg.getString(PROP_SETNAME_TYPES); 221 sSubDir = m_aCfg.getString(PROP_SUBDIR_TYPES ); 222 lFragments = m_lTypes; 223 } 224 break; 225 226 case 1: // filters 227 { 228 m_aLog.setDetailedInfo("generate set for filter ... "); 229 sSetName = m_aCfg.getString(PROP_SETNAME_FILTERS); 230 sSubDir = m_aCfg.getString(PROP_SUBDIR_FILTERS ); 231 lFragments = m_lFilters; 232 } 233 break; 234 235 case 2: // loaders 236 { 237 m_aLog.setDetailedInfo("generate set for frame loader ... "); 238 sSetName = m_aCfg.getString(PROP_SETNAME_LOADERS); 239 sSubDir = m_aCfg.getString(PROP_SUBDIR_LOADERS ); 240 lFragments = m_lLoaders; 241 } 242 break; 243 244 case 3: // handlers 245 { 246 m_aLog.setDetailedInfo("generate set for content handler ... "); 247 sSetName = m_aCfg.getString(PROP_SETNAME_HANDLERS); 248 sSubDir = m_aCfg.getString(PROP_SUBDIR_HANDLERS ); 249 lFragments = m_lHandlers; 250 } 251 break; 252 } 253 254 nItemCount += lFragments.size(); 255 256 getFragments( 257 new java.io.File(m_aFragmentsDir, sSubDir), 258 sSetName, 259 lFragments, 260 1, 261 sBuffer); 262 } 263 catch(java.util.NoSuchElementException exIgnore) 264 { continue; } 265 } 266 267 m_aLog.setDetailedInfo("generate package footer ... "); 268 sBuffer.append(XMLHelper.generateFooter()); 269 270 // Attention! 271 // If the package seem to be empty, it make no sense to generate a corresponding 272 // xml file. We should suppress writing of this file on disk completly ... 273 if (nItemCount < 1) 274 { 275 m_aLog.setWarning("Package is empty and will not result into a xml file on disk!? Please check configuration file."); 276 return; 277 } 278 m_aLog.setGlobalInfo("package contains "+nItemCount+" items"); 279 280 java.io.File aPackage = new File(sPackage); 281 m_aLog.setGlobalInfo("write temp package \""+aPackage.getPath()); // TODO encoding must be readed from the configuration 282 FileHelper.writeEncodedBufferToFile(aPackage, "UTF-8", false, sBuffer); // check for success is done inside this method! 283 } 284 285 //------------------------------------------- 286 /** TODO */ getFragments(java.io.File aDir , java.lang.String sSetName , java.util.Vector lFragments , int nPrettyTabs, java.lang.StringBuffer sBuffer )287 private void getFragments(java.io.File aDir , 288 java.lang.String sSetName , 289 java.util.Vector lFragments , 290 int nPrettyTabs, 291 java.lang.StringBuffer sBuffer ) 292 throws java.lang.Exception 293 { 294 if (lFragments.size()<1) 295 { 296 m_aLog.setWarning("List of fragments is empty!? Will be ignored ..."); 297 return; 298 } 299 300 java.util.Enumeration pFragments = lFragments.elements(); 301 java.lang.String sExtXcu = m_aCfg.getString(PROP_EXTENSION_XCU); 302 303 for (int tabs=0; tabs<nPrettyTabs; ++tabs) 304 sBuffer.append("\t"); 305 sBuffer.append("<node oor:name=\""+sSetName+"\">\n"); 306 ++nPrettyTabs; 307 308 // special mode for generating language packs. 309 // In such case we must live with some missing fragment files. 310 // Reason behind; Not all filters are realy localized. 311 // But we dont use a different fragment list. We try to locate 312 // any fragment file in its language-pack version ... 313 boolean bHandleLanguagePacks = m_aCfg.getBoolean(PROP_LANGUAGEPACK, false); 314 boolean bDebug = m_aCfg.getBoolean(PROP_DEBUG , false); 315 java.lang.String sEncoding = "UTF-8"; 316 if (bDebug) 317 sEncoding = "UTF-8Special"; 318 319 while(pFragments.hasMoreElements()) 320 { 321 java.lang.String sFragment = (java.lang.String)pFragments.nextElement(); 322 java.io.File aFragment = new java.io.File(aDir, sFragment+"."+sExtXcu); 323 324 // handle simple files only and check for existence! 325 if (!aFragment.exists()) 326 { 327 if (bHandleLanguagePacks) 328 { 329 m_aLog.setWarning("language fragment \""+aFragment.getPath()+"\" does not exist. Will be ignored."); 330 continue; 331 } 332 else 333 throw new java.io.IOException("fragment \""+aFragment.getPath()+"\" does not exists."); 334 } 335 336 if (!aFragment.isFile()) 337 { 338 m_aLog.setWarning("fragment \""+aFragment.getPath()+"\" seem to be not a valid file."); 339 continue; 340 } 341 342 // copy file content of original fragment 343 // Note: A FileNotFoundException will be thrown automaticly by the 344 // used reader objects. Let it break this method too. Our calli is interested 345 // on such errors :-) 346 m_aLog.setDetailedInfo("merge fragment \""+aFragment.getPath()+"\" ..."); 347 FileHelper.readEncodedBufferFromFile(aFragment, sEncoding, sBuffer); 348 349 sBuffer.append("\n"); 350 } 351 352 --nPrettyTabs; 353 for (int tabs=0; tabs<nPrettyTabs; ++tabs) 354 sBuffer.append("\t"); 355 sBuffer.append("</node>\n"); 356 } 357 } 358