package com.tesora.dve.sql.schema; /* * #%L * Tesora Inc. * Database Virtualization Engine * %% * Copyright (C) 2011 - 2014 Tesora Inc. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import com.tesora.dve.common.PEXmlUtils; import com.tesora.dve.common.catalog.CatalogEntity; import com.tesora.dve.common.catalog.PersistentTemplate; import com.tesora.dve.exceptions.PEException; import com.tesora.dve.sql.SchemaException; import com.tesora.dve.sql.ParserException.Pass; import com.tesora.dve.sql.schema.cache.CacheSegment; import com.tesora.dve.sql.schema.cache.SchemaCacheKey; import com.tesora.dve.sql.template.jaxb.TableTemplateType; import com.tesora.dve.sql.template.jaxb.Template; import com.tesora.dve.sql.util.ListOfPairs; import com.tesora.dve.sql.util.Pair; public class PETemplate extends Persistable<PETemplate, PersistentTemplate> { private Template definition; private String comment; private String dbmatch; private Pattern dbMatchPattern; private ListOfPairs<Pattern, TableTemplateType> templates = new ListOfPairs<Pattern, TableTemplateType>(); public PETemplate(SchemaContext sc, UnqualifiedName name, String body, String anyMatch, String anyComment) { super(getTemplateKey(name)); setName(name); setTemplate(build(body)); setComment(anyComment, definition.getComment()); setMatch(anyMatch, definition.getMatch()); setPersistent(sc,null,null); } private PETemplate(PersistentTemplate pt, SchemaContext pc) { super(getTemplateKey(pt.getName())); pc.startLoading(this, pt); setName(new UnqualifiedName(pt.getName())); setTemplate(build(pt.getDefinition())); setComment(pt.getComment(), definition.getComment()); setMatch(pt.getMatch(), definition.getMatch()); setPersistent(pc,pt,pt.getId()); pc.finishedLoading(this, pt); } public static PETemplate load(PersistentTemplate pt, SchemaContext pc) { PETemplate t = (PETemplate)pc.getLoaded(pt,getTemplateKey(pt.getName())); if (t == null) t = new PETemplate(pt,pc); return t; } public Template getTemplate() { return definition; } public void setTemplate(Template t) { definition = t; templates = new ListOfPairs<Pattern,TableTemplateType>(); for(TableTemplateType ttt : definition.getTabletemplate()) { Pattern p = Pattern.compile(ttt.getMatch()); templates.add(p,ttt); } } public String getDefinition() { return build(definition); } public String getComment() { return comment; } public void setComment(String c, String cFromTemplate) { setComment(StringUtils.isBlank(c) ? cFromTemplate : c); } public void setComment(String c) { comment = c; } public String getMatch() { return dbmatch; } public void setMatch(String c, String cFromTemplate) { setMatch(StringUtils.isBlank(c) ? cFromTemplate : c); } public void setMatch(String c) { dbmatch = c; dbMatchPattern = dbmatch != null ? Pattern.compile(dbmatch) : null; } @Override protected Class<? extends CatalogEntity> getPersistentClass() { return PersistentTemplate.class; } @Override protected int getID(PersistentTemplate p) { return p.getId(); } @Override protected PersistentTemplate lookup(SchemaContext sc) throws PEException { return null; } @Override protected PersistentTemplate createEmptyNew(SchemaContext sc) throws PEException { return new PersistentTemplate(getName().getUnquotedName().get(), build(definition), dbmatch, comment); } @Override protected void populateNew(SchemaContext sc, PersistentTemplate p) throws PEException { } @Override protected void updateExisting(SchemaContext sc, PersistentTemplate p) throws PEException { p.setDefinition(getDefinition()); p.setMatch(("".equals(dbmatch) ? null : dbmatch)); p.setComment(("".equals(comment) ? null : comment)); } @Override public Persistable<PETemplate, PersistentTemplate> reload(SchemaContext toContext) throws PEException { PersistentTemplate pt = toContext.getCatalog().findTemplate(getName().get()); if (pt == null) return null; return PETemplate.load(pt, toContext); } @Override protected Persistable<PETemplate, PersistentTemplate> load( SchemaContext sc, PersistentTemplate p) throws PEException { return new PETemplate(sc, new UnqualifiedName(p.getName()), p.getDefinition(), p.getMatch(), p.getComment()); } @Override protected String getDiffTag() { return "Template"; } public TableTemplateType findMatch(String tableName) { for(Pair<Pattern, TableTemplateType> p : templates) { Matcher m = p.getFirst().matcher(tableName); if (m.matches()) return p.getSecond(); } return null; } public boolean isMatch(UnqualifiedName dbName) { if (dbMatchPattern == null) return false; String str = dbName.getUnquotedName().get(); Matcher m = dbMatchPattern.matcher(str); return m.matches(); } public static Template build(String in) { try { return PEXmlUtils.unmarshalJAXB(in, Template.class); } catch (PEException pe) { throw new SchemaException(Pass.SECOND, "Unable to unmarshall template definition",pe); } } public static String build(Template t) { try { return PEXmlUtils.marshalJAXB(t); } catch (PEException pe) { throw new SchemaException(Pass.PLANNER, "Unable to marshall template definition",pe); } } public static SchemaCacheKey<PETemplate> getTemplateKey(UnqualifiedName n) { return getTemplateKey(n.getUnquotedName().get()); } public static SchemaCacheKey<PETemplate> getTemplateKey(String n) { return new TemplateCacheKey(n); } private static class TemplateCacheKey extends SchemaCacheKey<PETemplate> { /** * */ private static final long serialVersionUID = 1L; String name; public TemplateCacheKey(String n) { name = n; } @Override public CacheSegment getCacheSegment() { return CacheSegment.TEMPLATE; } @Override public int hashCode() { return initHash(PETemplate.class,name.hashCode()); } @Override public boolean equals(Object o) { if (o instanceof TemplateCacheKey) { TemplateCacheKey oct = (TemplateCacheKey) o; return name.equals(oct.name); } return false; } @Override public PETemplate load(SchemaContext sc) { PersistentTemplate ss = sc.getCatalog().findTemplate(name); if (ss == null) return null; return PETemplate.load(ss, sc); } @Override public String toString() { return "PETemplate:" + name; } } }