1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.taskdefs.optional.ide;
  18. import com.ibm.ivj.util.base.ExportCodeSpec;
  19. import com.ibm.ivj.util.base.ImportCodeSpec;
  20. import com.ibm.ivj.util.base.IvjException;
  21. import com.ibm.ivj.util.base.Package;
  22. import com.ibm.ivj.util.base.Project;
  23. import com.ibm.ivj.util.base.ProjectEdition;
  24. import com.ibm.ivj.util.base.ToolEnv;
  25. import com.ibm.ivj.util.base.Type;
  26. import com.ibm.ivj.util.base.Workspace;
  27. import java.io.File;
  28. import java.util.Date;
  29. import java.util.Enumeration;
  30. import java.util.Vector;
  31. import org.apache.tools.ant.BuildException;
  32. import org.apache.tools.ant.DirectoryScanner;
  33. /**
  34. * Helper class for VAJ tasks. Holds Workspace singleton and
  35. * wraps IvjExceptions into BuildExceptions
  36. *
  37. */
  38. abstract class VAJLocalUtil implements VAJUtil {
  39. // singleton containing the VAJ workspace
  40. private static Workspace workspace;
  41. /**
  42. * Wraps IvjException into a BuildException
  43. *
  44. * @return org.apache.tools.ant.BuildException
  45. * @param errMsg Additional error message
  46. * @param e IvjException which is wrapped
  47. */
  48. static BuildException createBuildException(
  49. String errMsg, IvjException e) {
  50. errMsg = errMsg + "\n" + e.getMessage();
  51. String[] errors = e.getErrors();
  52. if (errors != null) {
  53. for (int i = 0; i < errors.length; i++) {
  54. errMsg = errMsg + "\n" + errors[i];
  55. }
  56. }
  57. return new BuildException(errMsg, e);
  58. }
  59. /**
  60. * returns the current VAJ workspace.
  61. * @return com.ibm.ivj.util.base.Workspace
  62. */
  63. static Workspace getWorkspace() {
  64. if (workspace == null) {
  65. workspace = ToolEnv.connectToWorkspace();
  66. if (workspace == null) {
  67. throw new BuildException(
  68. "Unable to connect to Workspace! "
  69. + "Make sure you are running in VisualAge for Java.");
  70. }
  71. }
  72. return workspace;
  73. }
  74. //-----------------------------------------------------------
  75. // export
  76. //-----------------------------------------------------------
  77. /**
  78. * export packages
  79. */
  80. public void exportPackages(File dest,
  81. String[] includePatterns, String[] excludePatterns,
  82. boolean exportClasses, boolean exportDebugInfo,
  83. boolean exportResources, boolean exportSources,
  84. boolean useDefaultExcludes, boolean overwrite) {
  85. if (includePatterns == null || includePatterns.length == 0) {
  86. log("You must specify at least one include attribute. "
  87. + "Not exporting", MSG_ERR);
  88. } else {
  89. try {
  90. VAJWorkspaceScanner scanner = new VAJWorkspaceScanner();
  91. scanner.setIncludes(includePatterns);
  92. scanner.setExcludes(excludePatterns);
  93. if (useDefaultExcludes) {
  94. scanner.addDefaultExcludes();
  95. }
  96. scanner.scan();
  97. Package[] packages = scanner.getIncludedPackages();
  98. log("Exporting " + packages.length + " package(s) to "
  99. + dest, MSG_INFO);
  100. for (int i = 0; i < packages.length; i++) {
  101. log(" " + packages[i].getName(), MSG_VERBOSE);
  102. }
  103. ExportCodeSpec exportSpec = new ExportCodeSpec();
  104. exportSpec.setPackages(packages);
  105. exportSpec.includeJava(exportSources);
  106. exportSpec.includeClass(exportClasses);
  107. exportSpec.includeResources(exportResources);
  108. exportSpec.includeClassDebugInfo(exportDebugInfo);
  109. exportSpec.useSubdirectories(true);
  110. exportSpec.overwriteFiles(overwrite);
  111. exportSpec.setExportDirectory(dest.getAbsolutePath());
  112. getWorkspace().exportData(exportSpec);
  113. } catch (IvjException ex) {
  114. throw createBuildException("Exporting failed!", ex);
  115. }
  116. }
  117. }
  118. //-----------------------------------------------------------
  119. // load
  120. //-----------------------------------------------------------
  121. /**
  122. * Load specified projects.
  123. */
  124. public void loadProjects(Vector projectDescriptions) {
  125. Vector expandedDescs = getExpandedDescriptions(projectDescriptions);
  126. // output warnings for projects not found
  127. for (Enumeration e = projectDescriptions.elements(); e.hasMoreElements();) {
  128. VAJProjectDescription d = (VAJProjectDescription) e.nextElement();
  129. if (!d.projectFound()) {
  130. log("No Projects match the name " + d.getName(), MSG_WARN);
  131. }
  132. }
  133. log("Loading " + expandedDescs.size()
  134. + " project(s) into workspace", MSG_INFO);
  135. for (Enumeration e = expandedDescs.elements();
  136. e.hasMoreElements();) {
  137. VAJProjectDescription d = (VAJProjectDescription) e.nextElement();
  138. ProjectEdition pe;
  139. if (d.getVersion().equals("*")) {
  140. pe = findLatestProjectEdition(d.getName(), false);
  141. } else if (d.getVersion().equals("**")) {
  142. pe = findLatestProjectEdition(d.getName(), true);
  143. } else {
  144. pe = findProjectEdition(d.getName(), d.getVersion());
  145. }
  146. try {
  147. log("Loading '" + pe.getName() + "', Version '"
  148. + ((pe.getVersionName() != null) ? pe.getVersionName()
  149. : "(" + pe.getVersionStamp() + ")")
  150. + "' into Workspace", MSG_VERBOSE);
  151. pe.loadIntoWorkspace();
  152. } catch (IvjException ex) {
  153. throw createBuildException("Project '" + d.getName()
  154. + "' could not be loaded.", ex);
  155. }
  156. }
  157. }
  158. /**
  159. * return project descriptions containing full project names instead
  160. * of patterns with wildcards.
  161. */
  162. private Vector getExpandedDescriptions(Vector projectDescs) {
  163. Vector expandedDescs = new Vector(projectDescs.size());
  164. try {
  165. String[] projectNames =
  166. getWorkspace().getRepository().getProjectNames();
  167. for (int i = 0; i < projectNames.length; i++) {
  168. for (Enumeration e = projectDescs.elements();
  169. e.hasMoreElements();) {
  170. VAJProjectDescription d = (VAJProjectDescription) e.nextElement();
  171. String pattern = d.getName();
  172. if (VAJWorkspaceScanner.match(pattern, projectNames[i])) {
  173. d.setProjectFound();
  174. expandedDescs.addElement(new VAJProjectDescription(projectNames[i],
  175. d.getVersion()));
  176. break;
  177. }
  178. }
  179. }
  180. } catch (IvjException e) {
  181. throw createBuildException("VA Exception occurred: ", e);
  182. }
  183. return expandedDescs;
  184. }
  185. /**
  186. * Finds a specific project edition in the repository.
  187. *
  188. * @param name project name
  189. * @param versionName project version name
  190. * @return com.ibm.ivj.util.base.ProjectEdition the specified edition
  191. */
  192. private ProjectEdition findProjectEdition(
  193. String name, String versionName) {
  194. try {
  195. ProjectEdition[] editions = null;
  196. editions = getWorkspace().getRepository().getProjectEditions(name);
  197. if (editions == null) {
  198. throw new BuildException("Project " + name + " doesn't exist");
  199. }
  200. ProjectEdition pe = null;
  201. for (int i = 0; i < editions.length && pe == null; i++) {
  202. if (versionName.equals(editions[i].getVersionName())) {
  203. pe = editions[i];
  204. }
  205. }
  206. if (pe == null) {
  207. throw new BuildException("Version " + versionName
  208. + " of Project " + name + " doesn't exist");
  209. }
  210. return pe;
  211. } catch (IvjException e) {
  212. throw createBuildException("VA Exception occurred: ", e);
  213. }
  214. }
  215. /**
  216. * Finds the latest project edition in the repository.
  217. *
  218. * @param name project name
  219. * @param includeOpenEditions include open/scratch editions in the search?
  220. * @return com.ibm.ivj.util.base.ProjectEdition the specified edition
  221. */
  222. private ProjectEdition findLatestProjectEdition(
  223. String name,
  224. boolean includeOpenEditions) {
  225. try {
  226. ProjectEdition[] editions = null;
  227. editions = getWorkspace().getRepository().getProjectEditions(name);
  228. if (editions == null) {
  229. throw new BuildException("Project " + name + " doesn't exist");
  230. }
  231. // find latest (versioned) project edition by date
  232. ProjectEdition pe = null;
  233. // Let's hope there are no projects older than the epoch ;-)
  234. Date latestStamp = new Date(0);
  235. for (int i = 0; i < editions.length; i++) {
  236. if (!includeOpenEditions && !editions[i].isVersion()) {
  237. continue;
  238. }
  239. if (latestStamp.before(editions[i].getVersionStamp())) {
  240. latestStamp = editions[i].getVersionStamp();
  241. pe = editions[i];
  242. }
  243. }
  244. if (pe == null) {
  245. throw new BuildException("Can't determine latest edition for project " + name);
  246. }
  247. log("Using version " + ((pe.getVersionName() != null) ? pe.getVersionName()
  248. : "(" + pe.getVersionStamp() + ")")
  249. + " of " + pe.getName(), MSG_INFO);
  250. return pe;
  251. } catch (IvjException e) {
  252. throw createBuildException("VA Exception occurred: ", e);
  253. }
  254. }
  255. //-----------------------------------------------------------
  256. // import
  257. //-----------------------------------------------------------
  258. /**
  259. * Do the import.
  260. */
  261. public void importFiles(
  262. String importProject, File srcDir,
  263. String[] includePatterns, String[] excludePatterns,
  264. boolean importClasses, boolean importResources,
  265. boolean importSources, boolean useDefaultExcludes)
  266. throws BuildException {
  267. if (importProject == null || "".equals(importProject)) {
  268. throw new BuildException("The VisualAge for Java project "
  269. + "name is required!");
  270. }
  271. ImportCodeSpec importSpec = new ImportCodeSpec();
  272. importSpec.setDefaultProject(getVAJProject(importProject));
  273. DirectoryScanner ds = new DirectoryScanner();
  274. ds.setBasedir(srcDir);
  275. ds.setIncludes(includePatterns);
  276. ds.setExcludes(excludePatterns);
  277. if (useDefaultExcludes) {
  278. ds.addDefaultExcludes();
  279. }
  280. ds.scan();
  281. Vector classes = new Vector();
  282. Vector sources = new Vector();
  283. Vector resources = new Vector();
  284. scanForImport(srcDir, ds.getIncludedFiles(), classes, sources, resources);
  285. StringBuffer summaryLog = new StringBuffer("Importing ");
  286. addFilesToImport(importSpec, importClasses, classes, "Class", summaryLog);
  287. addFilesToImport(importSpec, importSources, sources, "Java", summaryLog);
  288. addFilesToImport(importSpec, importResources, resources, "Resource", summaryLog);
  289. importSpec.setResourcePath(srcDir.getAbsolutePath());
  290. summaryLog.append(" into the project '");
  291. summaryLog.append(importProject);
  292. summaryLog.append("'.");
  293. log(summaryLog.toString(), MSG_INFO);
  294. try {
  295. Type[] importedTypes = getWorkspace().importData(importSpec);
  296. if (importedTypes == null) {
  297. throw new BuildException("Unable to import into Workspace!");
  298. } else {
  299. log(importedTypes.length + " types imported", MSG_DEBUG);
  300. for (int i = 0; i < importedTypes.length; i++) {
  301. log(importedTypes[i].getPackage().getName()
  302. + "." + importedTypes[i].getName()
  303. + " into " + importedTypes[i].getProject().getName(),
  304. MSG_DEBUG);
  305. }
  306. }
  307. } catch (IvjException ivje) {
  308. throw createBuildException("Error while importing into workspace: ",
  309. ivje);
  310. }
  311. }
  312. /**
  313. * get a project from the Workspace.
  314. */
  315. static Project getVAJProject(String importProject) {
  316. Project found = null;
  317. Project[] currentProjects = getWorkspace().getProjects();
  318. for (int i = 0; i < currentProjects.length; i++) {
  319. Project p = currentProjects[i];
  320. if (p.getName().equals(importProject)) {
  321. found = p;
  322. break;
  323. }
  324. }
  325. if (found == null) {
  326. try {
  327. found = getWorkspace().createProject(importProject, true);
  328. } catch (IvjException e) {
  329. throw createBuildException("Error while creating Project "
  330. + importProject + ": ", e);
  331. }
  332. }
  333. return found;
  334. }
  335. /**
  336. * Sort the files into classes, sources, and resources.
  337. */
  338. private void scanForImport(
  339. File dir,
  340. String[] files,
  341. Vector classes,
  342. Vector sources,
  343. Vector resources) {
  344. for (int i = 0; i < files.length; i++) {
  345. String file = (new File(dir, files[i])).getAbsolutePath();
  346. if (file.endsWith(".java") || file.endsWith(".JAVA")) {
  347. sources.addElement(file);
  348. } else
  349. if (file.endsWith(".class") || file.endsWith(".CLASS")) {
  350. classes.addElement(file);
  351. } else {
  352. // for resources VA expects the path relative to the resource path
  353. resources.addElement(files[i]);
  354. }
  355. }
  356. }
  357. /**
  358. * Adds files to an import specification. Helper method
  359. * for importFiles()
  360. *
  361. * @param spec import specification
  362. * @param doImport only add files if doImport is true
  363. * @param files the files to add
  364. * @param fileType type of files (Source/Class/Resource)
  365. * @param summaryLog buffer for logging
  366. */
  367. private void addFilesToImport(ImportCodeSpec spec, boolean doImport,
  368. Vector files, String fileType,
  369. StringBuffer summaryLog) {
  370. if (doImport) {
  371. String[] fileArr = new String[files.size()];
  372. files.copyInto(fileArr);
  373. try {
  374. // here it is assumed that fileType is one of the
  375. // following strings: // "Java", "Class", "Resource"
  376. String methodName = "set" + fileType + "Files";
  377. Class[] methodParams = new Class[]{fileArr.getClass()};
  378. java.lang.reflect.Method method =
  379. spec.getClass().getDeclaredMethod(methodName, methodParams);
  380. method.invoke(spec, new Object[]{fileArr});
  381. } catch (Exception e) {
  382. throw new BuildException(e);
  383. }
  384. if (files.size() > 0) {
  385. logFiles(files, fileType);
  386. summaryLog.append(files.size());
  387. summaryLog.append(" " + fileType.toLowerCase() + " file");
  388. summaryLog.append(files.size() > 1 ? "s, " : ", ");
  389. }
  390. }
  391. }
  392. /**
  393. * Logs a list of file names to the message log
  394. * @param fileNames java.util.Vector file names to be logged
  395. * @param type java.lang.String file type
  396. */
  397. private void logFiles(Vector fileNames, String fileType) {
  398. log(fileType + " files found for import:", MSG_VERBOSE);
  399. for (Enumeration e = fileNames.elements(); e.hasMoreElements();) {
  400. log(" " + e.nextElement(), MSG_VERBOSE);
  401. }
  402. }
  403. }