001package io.ebeaninternal.extraddl.model; 002 003import io.ebean.annotation.Platform; 004import org.slf4j.Logger; 005import org.slf4j.LoggerFactory; 006 007import javax.xml.bind.JAXBContext; 008import javax.xml.bind.JAXBException; 009import javax.xml.bind.Unmarshaller; 010import java.io.IOException; 011import java.io.InputStream; 012 013import static io.ebeaninternal.api.PlatformMatch.matchPlatform; 014 015/** 016 * Read ExtraDdl from an XML document. 017 */ 018public class ExtraDdlXmlReader { 019 020 private static final Logger logger = LoggerFactory.getLogger(ExtraDdlXmlReader.class); 021 022 /** 023 * Return the combined extra DDL that should be run given the platform name. 024 */ 025 public static String buildExtra(Platform platform, boolean drops) { 026 return buildExtra(platform, drops, read("/extra-ddl.xml")); 027 } 028 029 /** 030 * Return any extra DDL for supporting partitioning given the database platform. 031 */ 032 public static String buildPartitioning(Platform platform) { 033 return buildExtra(platform, false, readBuiltinTablePartitioning()); 034 } 035 036 private static String buildExtra(Platform platform, boolean drops, ExtraDdl read) { 037 038 if (read == null) { 039 return null; 040 } 041 042 StringBuilder sb = new StringBuilder(300); 043 for (DdlScript script : read.getDdlScript()) { 044 if (script.isDrop() == drops && matchPlatform(platform, script.getPlatforms())) { 045 logger.debug("include script {}", script.getName()); 046 String value = script.getValue(); 047 sb.append(value); 048 if (value.lastIndexOf(';') == -1) { 049 // add statement terminator as we didn't find one 050 sb.append(";"); 051 } 052 sb.append("\n"); 053 } 054 } 055 return sb.toString(); 056 } 057 058 /** 059 * Read the builtin extra ddl. (Stored procedures, tvp types etc) 060 */ 061 public static ExtraDdl readBuiltin() { 062 return read("/io/ebeaninternal/dbmigration/builtin-extra-ddl.xml"); 063 } 064 065 /** 066 * Read the builtin extra ddl to support table partitioning. 067 */ 068 public static ExtraDdl readBuiltinTablePartitioning() { 069 return read("/io/ebeaninternal/dbmigration/builtin-extra-ddl-partitioning.xml"); 070 } 071 072 /** 073 * Read the extra ddl. 074 */ 075 public static ExtraDdl read() { 076 return read("/extra-ddl.xml"); 077 } 078 079 /** 080 * Read and return a ExtraDdl from an xml document at the given resource path. 081 */ 082 private static ExtraDdl read(String resourcePath) { 083 084 try (InputStream is = ExtraDdlXmlReader.class.getResourceAsStream(resourcePath)) { 085 if (is == null) { 086 // we expect this and check for null 087 return null; 088 } 089 return read(is); 090 } catch (IOException e) { 091 throw new IllegalStateException("Error on auto close of " + resourcePath, e); 092 } 093 } 094 095 /** 096 * Read and return a ExtraDdl from an xml document. 097 */ 098 public static ExtraDdl read(InputStream is) { 099 100 try { 101 JAXBContext jaxbContext = JAXBContext.newInstance(ExtraDdl.class); 102 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 103 return (ExtraDdl) unmarshaller.unmarshal(is); 104 105 } catch (JAXBException e) { 106 throw new RuntimeException(e); 107 } 108 } 109}