001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.q2.install; 020 021import org.apache.commons.cli.*; 022 023import java.io.File; 024import java.io.FileOutputStream; 025import java.io.IOException; 026import java.io.InputStream; 027import java.util.List; 028 029/** 030 * Command-line tool that extracts the bundled installation skeletons under 031 * {@code META-INF/q2/installs/} into a target directory. 032 * 033 * @author vsalaman 034 */ 035public class Install 036{ 037 /** Default constructor; no instance state to initialise. */ 038 public Install() {} 039 private static final String DEFAULT_PREFIX = "META-INF/q2/installs/"; 040 041 /** 042 * Entry point: parses the command-line options and invokes {@link #install}. 043 * 044 * @param args command-line arguments (see option descriptions in source) 045 * @throws Exception if option parsing or extraction fails 046 */ 047 public static void main(String[] args) throws Exception 048 { 049 CommandLineParser parser = new DefaultParser(); 050 Options options = new Options (); 051 options.addOption ("p", "prefix", true, String.format("prefix, defaults to '%s'", DEFAULT_PREFIX)); 052 options.addOption ("q", "quiet", false, "do not show information about files being extracted"); 053 options.addOption ("f", "force", false, "override existing files in output directory"); 054 options.addOption ("o", "outputDir", true, "output directory, defaults to " + new File(".").getAbsolutePath()); 055 options.addOption ("h", "help", false, "Usage information"); 056 057 CommandLine line = parser.parse (options, args); 058 if (line.hasOption ("h")) { 059 HelpFormatter helpFormatter = new HelpFormatter (); 060 helpFormatter.printHelp ("install", options); 061 return; 062 } 063 String prefix = line.hasOption("p") ? line.getOptionValue("prefix") : DEFAULT_PREFIX; 064 String outputBasePath = line.hasOption("o") ? line.getOptionValue("o") : "."; 065 new Install().install( 066 line.hasOption("f"), 067 new File(outputBasePath), 068 !line.hasOption("q"), 069 prefix 070 ); 071 } 072 073 /** 074 * Extracts every classpath resource under {@code prefix} into {@code outputBasePath}. 075 * 076 * @param allowOverride overwrite existing files when {@code true} 077 * @param outputBasePath destination directory (created when missing) 078 * @param verbose log each extracted file when {@code true} 079 * @param prefix classpath prefix to scan 080 * @throws IOException if classpath enumeration or extraction fails 081 */ 082 public void install(boolean allowOverride,File outputBasePath, boolean verbose, String prefix) throws IOException 083 { 084 if(!outputBasePath.exists()) 085 { 086 outputBasePath.mkdirs(); 087 } 088 089 List<String> moduleConfigs = ModuleUtils.getModuleEntries(prefix); 090 for (String resource : moduleConfigs) 091 { 092 final String s = resource.substring(prefix.length()); 093 int end = s.lastIndexOf("/"); 094 String dirPrefix = end < 0 ? null : s.substring(0, end); 095 if (dirPrefix != null) 096 { 097 File dir = new File(outputBasePath,dirPrefix); 098 if (!dir.exists()) { 099 if (verbose) 100 System.out.println("Created " + dir.getAbsolutePath()); 101 dir.mkdirs(); 102 } 103 } 104 String path = s.replaceAll("/", "\\" + File.separator); 105 File outputFile = new File(outputBasePath,path); 106 if(outputFile.exists() && !allowOverride) 107 { 108 if (verbose) { 109 System.out.printf ("%s exists, use --force to override%n", outputFile); 110 } 111 //outputFile = new File(outputBasePath,path+".sample"); 112 continue; 113 } 114 copyResourceToFile(resource, outputFile, verbose); 115 } 116 } 117 118 private void copyResourceToFile(String resource, File destination, boolean verbose) throws IOException 119 { 120 InputStream source=null; 121 try 122 { 123 source = getClass().getClassLoader().getResourceAsStream(resource); 124 FileOutputStream output = new FileOutputStream(destination); 125 if (verbose) { 126 System.out.println("extracting " + destination); 127 } 128 try 129 { 130 byte[] buffer = new byte[4096]; 131 int n; 132 while (-1 != (n = source.read(buffer))) 133 { 134 output.write(buffer, 0, n); 135 } 136 } 137 finally 138 { 139 try { output.close(); } catch (IOException ex) { 140 ex.printStackTrace(System.err); 141 } 142 } 143 } 144 finally 145 { 146 try { if(source!=null) source.close(); } catch (IOException ex) { 147 ex.printStackTrace(System.err); 148 } 149 } 150 } 151}