Skip to main content
summaryrefslogtreecommitdiffstats
blob: ec2249b3b907d2f2c3b4e34d8b2199fa6380538a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
/***************************************************************************************************
 * Copyright (c) 2005 Eteration A.S. and Gorkem Ercan. All rights reserved. This program and the
 * accompanying materials are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Gorkem Ercan - initial API and implementation
 *               
 **************************************************************************************************/
package org.eclipse.jst.server.generic.core.internal.publishers;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants;
//import org.eclipse.ant.internal.ui.launchConfigurations.IAntLaunchConfigurationConstants;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.jst.server.generic.core.internal.CorePlugin;
import org.eclipse.jst.server.generic.core.internal.GenericPublisher;
import org.eclipse.jst.server.generic.core.internal.GenericServer;
import org.eclipse.jst.server.generic.core.internal.GenericServerCoreMessages;
import org.eclipse.jst.server.generic.internal.core.util.FileUtil;
import org.eclipse.jst.server.generic.servertype.definition.Module;
import org.eclipse.jst.server.generic.servertype.definition.PublisherData;
import org.eclipse.ui.externaltools.internal.model.IExternalToolConstants;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IModuleArtifact;
import org.eclipse.wst.server.core.internal.ServerPlugin;
import org.osgi.framework.Bundle;

/**
 * Ant based publisher. All the properties defined in the server definition file
 * are passed into the ANT build file as properties. In addition to the
 * properties defined in the server definition <I>module.dir</I>,
 * <I>module.name,</I> and <I>server.publish.dir</I> are computed and passed
 * to the definition file.
 * <ul>
 * <li>module.dir: includes the root of the module project file</li>
 * <li>module.name: the name of the module</li>
 * <li>server.publish.dir: the directory to put the deployment units</li>
 * <li>project.working.dir: the working dir of the project that deployed module
 * is in</li>
 * </ul>
 * 
 * @author Gorkem Ercan
 */

public class AntPublisher extends GenericPublisher {
	private static final String JAR_PROTOCOL_PREFIX = "jar"; //$NON-NLS-1$

	/**
	 * publisher id for ANT publisher.
	 */
	public static final String PUBLISHER_ID = "org.eclipse.jst.server.generic.antpublisher"; //$NON-NLS-1$

	protected static final String PROP_SERVER_PUBLISH_DIR = "server.publish.dir";//$NON-NLS-1$

	protected static final String PROP_PROJECT_WORKING_DIR = "project.working.dir";//$NON-NLS-1$

	protected static final String PROP_MODULE_DIR = "module.dir";//$NON-NLS-1$

	protected static final String PROP_MODULE_NAME = "module.name";//$NON-NLS-1$

	protected static final String PROP_CONTEXT_ROOT = "contextRoot";//$NON-NLS-1$

	protected static final String PROP_PROJECT_NAME = "project.name";//$NON-NLS-1$
	
	protected static final String PROP_PROJECT_LOCATION = "project.location";

	protected static final String MODULE_PUBLISH_TARGET_PREFIX = "target.publish."; //$NON-NLS-1$

	protected static final String MODULE_UNPUBLISH_TARGET_PREFIX = "target.unpublish.";//$NON-NLS-1$

	protected static final String DATA_NAME_BUILD_FILE = "build.file";//$NON-NLS-1$

	protected static final String PROP_MODULE_ARCHIVE_NAME = "module.archive.name"; //$NON-NLS-1$

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wtp.server.core.model.IPublisher#publish(org.eclipse.wtp.server.core.resources.IModuleResource[],
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public IStatus[] publish(IModuleArtifact[] resource, IProgressMonitor monitor) {
		if (getModule().length > 1)// only respond to root module calls.
			return null;
		try {
			if (monitor.isCanceled())
				return null;
			assembleModule(monitor);
			File file = getCustomBuildFile();
			if ( file == null){// no user selected build file use the adapter default.
				file = computeBuildFile();
			}
			runAnt(file.toString(), getPublishTargetsForModule(), getPublishProperties(), monitor);
		} catch (CoreException e) {
			IStatus s = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 0, GenericServerCoreMessages.errorPublishAntpublisher, e);
			CorePlugin.getDefault().getLog().log(s);
			return new IStatus[] { s };
		}
		return null;
	}

	protected void assembleModule(IProgressMonitor monitor) throws CoreException {
		AbstractModuleAssembler assembler = AbstractModuleAssembler.Factory.getModuleAssembler(getModule()[0], getServer());
		assembler.assemble(monitor);
	}

	/**
	 * Returns the custom build file that user selected. Or returns null;
	 * @return
	 * @throws CoreException 
	 */
	private File getCustomBuildFile() throws CoreException {
		String filename = (String)getServer().getServerInstanceProperties().get( GenericServer.PROP_CUSTOM_BUILD_SCRIPT );
		if( filename != null && filename.length()>0 ){
			filename = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution( filename );
			File file = new File(filename);
			if ( !file.exists() ){
				throw new CoreException(new Status(IStatus.ERROR,CorePlugin.PLUGIN_ID,
						"Selected build file does not exist."));
			}
			return file;
		}
		return null;
	}
	/**
	 * 
	 * @return file
	 * @throws CoreException
	 */
	private File computeBuildFile() throws CoreException {
		Bundle bundle = Platform.getBundle(getServerRuntime().getServerTypeDefinition().getConfigurationElementNamespace());
		URL bundleUrl = bundle.getEntry(getBuildFile());
		URL fileURL = FileUtil.resolveURL(bundleUrl);
		if (fileURL.getProtocol().equals(JAR_PROTOCOL_PREFIX)) {
			OutputStream os = null;
			InputStream is = null;
			try {
				String filename = fileURL.getPath();
				String jarname = fileURL.getFile().substring(0, filename.indexOf('!'));

				File jarFile = new File(new URL(jarname).getFile());
				JarFile jar = new JarFile(jarFile);
				File tmpFile = FileUtil.createTempFile(getBuildFile(), CorePlugin.getDefault().getStateLocation().toOSString());
				os = new FileOutputStream(tmpFile);
				String entryname = getBuildFile();
				if (entryname.startsWith("/"))//$NON-NLS-1$
					entryname = entryname.substring(1);
				JarEntry entry = jar.getJarEntry(entryname);
				is = jar.getInputStream(entry);
				FileUtil.copy(is, os);
				return tmpFile;
			} catch (IOException e) {
				IStatus s = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 0, "error creating temporary build file", e);//$NON-NLS-1$
				CorePlugin.getDefault().getLog().log(s);
				throw new CoreException(s);
			} finally {
				try {
					if (is != null)
						is.close();
					if (os != null)
						os.close();
				} catch (IOException e) {
					// ignore
				}
			}
		} 
		return FileUtil.resolveFile(fileURL);
	
	}

	private String getPublishTargetsForModule() {
		return doGetTargets(MODULE_PUBLISH_TARGET_PREFIX + getModuleTypeId());
	}

	private String getUnpublishTargetsForModule() {
		return doGetTargets(MODULE_UNPUBLISH_TARGET_PREFIX + getModuleTypeId());
	}

	private String doGetTargets(String dataname) {
		StringBuffer buffer = new StringBuffer();
		Iterator iterator = getServerRuntime().getServerTypeDefinition().getPublisher(PUBLISHER_ID).getPublisherdata().iterator();
		while (iterator.hasNext()) {
			PublisherData data = (PublisherData) iterator.next();
			if (dataname.equals(data.getDataname())) {
				if (buffer.length() > 0)
					buffer.append(",");//$NON-NLS-1$
				buffer.append(data.getDatavalue());
			}
		}
		return buffer.toString();
	}

	private String getModuleTypeId() {
		return getModule()[0].getModuleType().getId();
	}

	private String getBuildFile() {
		Iterator iterator = getServerRuntime().getServerTypeDefinition().getPublisher(PUBLISHER_ID).getPublisherdata().iterator();
		while (iterator.hasNext()) {
			PublisherData data = (PublisherData) iterator.next();
			if (DATA_NAME_BUILD_FILE.equals(data.getDataname()))
				return getServerRuntime().getServerTypeDefinition().getResolver().resolveProperties(data.getDatavalue());
		}
		return null;
	}

	private Map getPublishProperties() {
		Map props = new HashMap();
		// pass all properties to build file.
		Map serverProperties = getServer().getServerInstanceProperties();
		Map properties = getServerRuntime().getServerInstanceProperties();
		properties.putAll(serverProperties);
		Iterator propertyIterator = properties.keySet().iterator();
		while (propertyIterator.hasNext()) {
			String property = (String) propertyIterator.next();
			String value = (String) properties.get(property);
			if (value != null && value.trim().length() > 0)
				props.put(property, properties.get(property));
		}
		Module module = getServerRuntime().getServerTypeDefinition().getModule(getModuleTypeId());
		String modDir = module.getPublishDir();
		modDir = getServerRuntime().getServerTypeDefinition().getResolver().resolveProperties(modDir);
		IModule webModule = getModule()[0];

		String moduleName = guessModuleName(webModule);
		String contextRoot = guessContextRoot(webModule);
		props.put(PROP_PROJECT_WORKING_DIR, getProjectWorkingLocation().toString());
		props.put(PROP_MODULE_NAME, moduleName);
		props.put(PROP_CONTEXT_ROOT, contextRoot);
			
		if (isModuleType(webModule, "jst.ear")) {//$NON-NLS-1$
			props.put(PROP_MODULE_ARCHIVE_NAME, moduleName + ".ear"); //$NON-NLS-1$
		} else if (isModuleType(webModule, "jst.web")) { //$NON-NLS-1$
			props.put(PROP_MODULE_ARCHIVE_NAME, moduleName + ".war"); //$NON-NLS-1$
		} else if (isModuleType(webModule, "jst.ejb")) { //$NON-NLS-1$
			props.put(PROP_MODULE_ARCHIVE_NAME, moduleName + ".jar"); //$NON-NLS-1$
		}
		if (webModule.getProject() != null) {
			props.put(PROP_MODULE_DIR, getModuleWorkingDir().toString());
			props.put(PROP_PROJECT_NAME, webModule.getProject().getName());
			props.put(PROP_PROJECT_LOCATION, webModule.getProject().getLocation().toString());
		}
		props.put(PROP_SERVER_PUBLISH_DIR, modDir);
		return props;
	}

	private IPath getModuleWorkingDir() {
		return getProjectWorkingLocation().append(getModule()[0].getProject().getName());
	}

	private IPath getProjectWorkingLocation() {
		return ServerPlugin.getInstance().getTempDirectory(getServer().getServer().getId());
	}

	private String guessModuleName(IModule module) {
		String moduleName = module.getName();
		if ("jst.web".equals(getModuleTypeId())) { //$NON-NLS-1$
			IWebModule webModule = (IWebModule) getModule()[0].loadAdapter(IWebModule.class, null);
			if (webModule == null) {
				return module.getName();
			}
			String contextRoot = webModule.getURI(module);
			moduleName = contextRoot.substring(0, contextRoot.lastIndexOf('.'));
		}
		return moduleName;
	}

	private String guessContextRoot(IModule module) {
		String moduleName = guessModuleName(module);
		String contextRoot = moduleName;
		if ("jst.web".equals(getModuleTypeId())) { //$NON-NLS-1$
			IWebModule webModule = (IWebModule) getModule()[0].loadAdapter(IWebModule.class, null);
			if (webModule != null) {
				contextRoot = webModule.getContextRoot();
				if (contextRoot == null || contextRoot.length() == 0) {
					contextRoot = moduleName;
				}
			}
		}
		return contextRoot;
	}

	private void runAnt(String buildFile, String targets, Map properties, IProgressMonitor monitor) throws CoreException {
		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType type = launchManager
				.getLaunchConfigurationType(IAntLaunchConfigurationConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
		if (type == null) {
			IStatus s = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 0, GenericServerCoreMessages.antLauncherMissing, null);
			throw new CoreException(s);
		}
		ILaunchConfigurationWorkingCopy wc = type.newInstance(null, properties.get(PROP_MODULE_NAME) + " module publisher"); //$NON-NLS-1$
		wc.setContainer(null);
		wc.setAttribute(IExternalToolConstants.ATTR_LOCATION, buildFile);
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, "org.eclipse.ant.ui.AntClasspathProvider"); //$NON-NLS-1$
		wc.setAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_TARGETS, targets);
		wc.setAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTIES, properties);
		wc.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, false);
		wc.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, true);
		wc.setAttribute(IDebugUIConstants.ATTR_PRIVATE, true);

		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER, "org.eclipse.ant.ui.AntClasspathProvider"); //$NON-NLS-1$
		
		IVMInstall vmInstall = getServerRuntime().getVMInstall();
		if(vmInstall == null )//fallback to default VM if null.
			vmInstall = JavaRuntime.getDefaultVMInstall();
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, JavaRuntime.newJREContainerPath(vmInstall).toPortableString());

		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
				"org.eclipse.ant.internal.ui.antsupport.InternalAntRunner"); //$NON-NLS-1$
		wc.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, IAntUIConstants.REMOTE_ANT_PROCESS_FACTORY_ID);

		setupAntLaunchConfiguration(wc);

        if ( !monitor.isCanceled() )
        {
            ILaunchConfiguration launchConfig = wc.doSave();          
            launchConfig.launch(ILaunchManager.RUN_MODE, monitor, false, true);
        }    
	}

	/**
	 * Hook method for subclasses.
	 * 
	 * @param wc
	 */
	protected void setupAntLaunchConfiguration(ILaunchConfigurationWorkingCopy wc) {
		// nothing to do
	}

	private static boolean isModuleType(IModule module, String moduleTypeId) {
		if (module.getModuleType() != null && moduleTypeId.equals(module.getModuleType().getId()))
			return true;
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.server.generic.internal.core.GenericPublisher#unpublish(org.eclipse.wst.server.core.IModule,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public IStatus[] unpublish(IProgressMonitor monitor) {

		if (getModule().length > 1)// only respond to root module calls.
			return null;
		try {
			File file = computeBuildFile();
			runAnt(file.toString(), getUnpublishTargetsForModule(), getPublishProperties(), monitor);
		} catch (CoreException e) {
			IStatus s = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 0, GenericServerCoreMessages.errorRemoveModuleAntpublisher, e);
			return new IStatus[] { s };
		}
		return null;
	}
}

Back to the top