/***************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.cayenne.tools; import org.apache.cayenne.access.DataDomain; import org.apache.cayenne.access.DataNode; import org.apache.cayenne.access.DataPort; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.server.ServerRuntime; import org.apache.cayenne.di.Binder; import org.apache.cayenne.di.Key; import org.apache.cayenne.di.Module; import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.resource.FilesystemResourceLocator; import org.apache.cayenne.resource.ResourceLocator; import org.apache.cayenne.util.Util; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import java.io.File; import java.util.Collection; import java.util.HashSet; /** * A "cdataport" Ant task implementing a frontend to DataPort allowing porting * database data using Ant build scripts. * * @since 1.2: Prior to 1.2 DataPort classes were a part of cayenne-examples * package. * @deprecated since 4.0 */ @Deprecated public class DataPortTask extends CayenneTask { protected File projectFile; protected String maps; protected String srcNode; protected String destNode; protected String includeTables; protected String excludeTables; protected boolean cleanDest = true; public DataPortTask() { // set defaults this.cleanDest = true; } @Override public void execute() throws BuildException { log("*** 'cdataport' task is deprecated and will be removed after 4.0", Project.MSG_WARN); validateParameters(); String projectFileLocation = projectFile.getName(); Module dataPortModule = new Module() { public void configure(Binder binder) { FilesystemResourceLocator filesystemResourceLocator = new FilesystemResourceLocator(projectFile); binder.bind(ResourceLocator.class).toInstance(filesystemResourceLocator); binder.bind(Key.get(ResourceLocator.class, Constants.SERVER_RESOURCE_LOCATOR)) .toInstance(filesystemResourceLocator); } }; ServerRuntime runtime = new ServerRuntime(projectFileLocation, dataPortModule); DataDomain domain; ClassLoader threadContextClassLoader = Thread.currentThread() .getContextClassLoader(); try { // need to set context class loader so that cayenne can find jdbc // driver and // PasswordEncoder // TODO: andrus 04/11/2010 is this still relevant in 3.1? Thread.currentThread().setContextClassLoader( getClass().getClassLoader()); domain = runtime.getDataDomain(); } catch (Exception ex) { throw new BuildException( "Error loading Cayenne configuration from " + projectFile, ex); } finally { // set back to original ClassLoader Thread.currentThread().setContextClassLoader( threadContextClassLoader); } // perform project validation DataNode source = domain.getDataNode(srcNode); if (source == null) { throw new BuildException("srcNode not found in the project: " + srcNode); } DataNode destination = domain.getDataNode(destNode); if (destination == null) { throw new BuildException("destNode not found in the project: " + destNode); } log("Porting from '" + srcNode + "' to '" + destNode + "'."); AntDataPortDelegate portDelegate = new AntDataPortDelegate(this, maps, includeTables, excludeTables); DataPort dataPort = new DataPort(portDelegate); dataPort.setEntities(getAllEntities(source, destination)); dataPort.setCleaningDestination(cleanDest); dataPort.setSourceNode(source); dataPort.setDestinationNode(destination); try { dataPort.execute(); } catch (Exception e) { Throwable topOfStack = Util.unwindException(e); throw new BuildException("Error porting data: " + topOfStack.getMessage(), topOfStack); } } protected Collection<DbEntity> getAllEntities(DataNode source, DataNode target) { // use a set to exclude duplicates, though a valid project will probably // have // none... Collection<DbEntity> allEntities = new HashSet<DbEntity>(); for (DataMap map : source.getDataMaps()) { allEntities.addAll(map.getDbEntities()); } for (DataMap map : target.getDataMaps()) { allEntities.addAll(map.getDbEntities()); } log("Number of entities: " + allEntities.size(), Project.MSG_VERBOSE); if (allEntities.size() == 0) { log("No entities found for either source or target."); } return allEntities; } protected void validateParameters() throws BuildException { if (projectFile == null) { throw new BuildException( "Required 'projectFile' parameter is missing."); } if (!projectFile.exists()) { throw new BuildException("'projectFile' does not exist: " + projectFile); } if (srcNode == null) { throw new BuildException("Required 'srcNode' parameter is missing."); } if (destNode == null) { throw new BuildException( "Required 'destNode' parameter is missing."); } } public void setDestNode(String destNode) { this.destNode = destNode; } public void setExcludeTables(String excludeTables) { this.excludeTables = excludeTables; } public void setIncludeTables(String includeTables) { this.includeTables = includeTables; } public void setMaps(String maps) { this.maps = maps; } public void setProjectFile(File projectFile) { this.projectFile = projectFile; } public void setSrcNode(String srcNode) { this.srcNode = srcNode; } public void setCleanDest(boolean flag) { this.cleanDest = flag; } }