/* * Copyright 2010 NapkinDrawing LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.napkindrawing.dbversion.loader.jar; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.tools.ant.BuildException; import com.napkindrawing.dbversion.Profile; import com.napkindrawing.dbversion.Revision; import com.napkindrawing.dbversion.Version; import com.napkindrawing.dbversion.loader.ProfileLoader; import com.napkindrawing.dbversion.loader.ProfilesLoader; public class JarProfilesLoader extends JarLoader implements ProfilesLoader { ProfileLoader profileLoader; public boolean DEBUG = false; @Override public List<Profile> loadProfiles() { if(DEBUG) System.out.println("JarProfilesLoader.loadProfiles: " + getJarPath()); if(getJarPath() == null) { throw new BuildException("jarPath is null!"); } List<Profile> profiles = new ArrayList<Profile>(); Map<String,Profile> profilesByName = new HashMap<String,Profile>(); InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(getJarPath()); ZipInputStream zin = new ZipInputStream(in); ZipEntry entry = null; try { while((entry = zin.getNextEntry()) != null) { if(DEBUG) System.out.println(" Jar Entry [isDirectory:"+entry.isDirectory()+"] >>> " + entry.getName()); if(DEBUG) System.out.println(" " + entry.toString()); if(entry.getName().matches("\\AMETA-INF.*") || entry.isDirectory()) { if(DEBUG) System.out.println(" skippin!"); continue; } if(!entry.getName().matches("\\A[\\w\\-\\.\\:]+/\\d{5}.*\\.sql\\z")) { throw new BuildException("Unrecognized file in sql jar: " + entry.getName()); } String profileName = entry.getName().substring(0, entry.getName().indexOf("/")); if(DEBUG) System.out.println(" Profile: " + profileName); Profile profile = profilesByName.get(profileName); if(profile == null) { if(DEBUG) System.out.println(" Adding Profile"); profile = new Profile(); profile.setName(profileName); profiles.add(profile); profilesByName.put(profileName, profile); } String versionNameFull = entry.getName().substring(entry.getName().indexOf("/")+1); if(DEBUG) System.out.println(" Full version Name: " + versionNameFull); String versionNum = versionNameFull.substring(0,5); if(DEBUG) System.out.println(" Version Num: " + versionNum); String versionNameComment = versionNameFull.length() > 9 ? versionNameFull.replaceFirst("\\.sql", "").substring(6) : ""; byte[] sqlBytes = new byte[ (int) entry.getSize() ]; if(DEBUG) System.out.println(" Reading " + entry.getSize() + " bytes"); int count; byte[] sqlBuf = new byte[2048]; int totalCount = 0; while(( count = zin.read(sqlBuf)) != -1) { if(DEBUG) System.out.println(" arrayCopy(sqlBuf, 0, sqlBytes," + totalCount+","+count+")"); System.arraycopy(sqlBuf, 0, sqlBytes, totalCount, count); totalCount += count; } if(DEBUG) System.out.println(" Total bytes read: " + totalCount); String sql = new String(sqlBytes); if(DEBUG) System.out.println("==========SQL:========================================="); if(DEBUG) System.out.println(sql); if(DEBUG) System.out.println("======================================================"); Revision revision = new Revision(new Version(versionNum)); revision.setUpgradeScriptTemplate(sql); revision.assignUpgradeScriptTemplateChecksum(); revision.setName(versionNameComment); profile.getRevisions().add(revision); } } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } return profiles; } @Override public void setProfileLoader(ProfileLoader profileLoader) { this.profileLoader = profileLoader; } }