Skip to main content
summaryrefslogtreecommitdiffstats
blob: 05ea71086493f24635ed49ef0adb4fff0a942350 (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
/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20070509   182274 kathy@ca.ibm.com - Kathy Chan
 * 20080122   215048 kathy@ca.ibm.com - Kathy Chan
 * 20080613   236523 makandre@ca.ibm.com - Andrew Mak, Overwrite setting on Web service wizard is coupled with preference
 *******************************************************************************/
package org.eclipse.jst.ws.internal.consumption.common;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.codegen.merge.java.JControlModel;
import org.eclipse.emf.codegen.merge.java.JMerger;
import org.eclipse.emf.codegen.merge.java.facade.FacadeHelper;
import org.eclipse.emf.codegen.util.CodeGenUtil;
import org.eclipse.jst.ws.internal.consumption.ConsumptionMessages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.command.internal.env.common.FileResourceUtils;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.core.context.ResourceContext;
import org.eclipse.wst.command.internal.env.core.context.TransientResourceContext;
import org.eclipse.wst.common.environment.IStatusHandler;
import org.eclipse.wst.ws.internal.plugin.WSPlugin;
import org.eclipse.wst.ws.internal.preferences.PersistentMergeContext;
import org.eclipse.wst.ws.internal.wsrt.IMerger;
import org.eclipse.wst.ws.internal.wsrt.Merger;
import org.osgi.framework.Bundle;

/*
 * JavaMerger handles the merging of workspace files using JMerger.  If the URIs specified is not a file
 * in the workspace, it will be ignored.
 */
public class JavaMerger extends Merger implements IMerger {

	private static final String WST_WS = "org.eclipse.wst.ws";
	private static final String MERGE_XML = "merge.xml";
	private static final String JMERGER = "jmerger";
	
	private int size = 0; 
	private IFile[] workspaceFiles;
	private JMerger[] mergeModels;
	private JControlModel jMergeControlModel = null;
	private IStatus loadStatus;
	
	
	/*
	 * Convert the URI strings in the uris array to Eclipse IFiles and store in the workspaceFiles array. 
	 * Load the workspaceFiles into JMerger and store in the mergerModels array.  
	 * If the merger model cannot be obtained, null is stored in the mergerModels. 
	 * @see org.eclipse.wst.ws.internal.wsrt.IMerger#load(java.lang.String[])
	 */
	
	public IStatus load(IFile[] files) {
		
		loadStatus = Status.OK_STATUS;
		if (files != null) {
			workspaceFiles = files;
			PersistentMergeContext mergeContext = WSPlugin.getInstance().getMergeContext();
			if (mergeContext.isSkeletonMergeEnabled()) {
				// initialize JMerger
				initialize();
				
				if (jMergeControlModel != null) {
					// JMerger initialized properly
					size = files.length;
					mergeModels = new JMerger[size];
					
					for (int i = 0; i < size; i++) {
						JMerger jMerger = null;
						IFile file = null;
						InputStream inStream = null;
						
						file = files[i];
						if (file != null && file.exists()) {														
							try {
								inStream = file.getContents();
								if (inStream != null) {
									jMerger = new JMerger(jMergeControlModel);
									jMerger.setTargetCompilationUnit(jMerger.createCompilationUnitForInputStream(inStream));
								}
							} catch (CoreException e) {
								loadStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_FILE_MERGE_LOAD, file), e);
							} finally {
								if (inStream != null) {
									try {
										inStream.close();
									} catch (IOException e) {
										// ignore exceptions in closing file
									}
								}
							}				
						}
						mergeModels[i] = jMerger;
					}
				}
			}
		}
		return loadStatus;
	}

	/**
	 * Initializes the JMerge model
	 * File merge.xml in WebServicePlugin contains the rules for the merge.
	 * If the merge.xml file is not found, jMergeControlModel is leave as null.
	 */
	private void initialize() {
		if (jMergeControlModel == null) {
			FacadeHelper facadeHelper = CodeGenUtil.instantiateFacadeHelper(JMerger.DEFAULT_FACADE_HELPER_CLASS);
			jMergeControlModel = new JControlModel();

			Bundle        wsBundle = Platform.getBundle(WST_WS);
			IPath         mergePath      = new Path( JMERGER ).append( MERGE_XML );
			URL           fileURL        = FileLocator.find( wsBundle, mergePath, null);
			jMergeControlModel.initialize(facadeHelper, fileURL.toString());
		}
		return;
	}
	
	/**
	 * Merge the current contents of the workspaceFiles with the mergeModels that had been stored earlier.   
	 * Then write the merged contents back to the file.
	 * @param monitor
	 * @param statusHandler
	 * @return IStatus
	 */
	public IStatus merge(IProgressMonitor monitor, IStatusHandler statusHandler) {
		
		IStatus status = Status.OK_STATUS;
		
		if (loadStatus != null && loadStatus.getSeverity() == IStatus.ERROR) {
			return loadStatus;
		}
		
		PersistentMergeContext mergeContext = WSPlugin.getInstance().getMergeContext();
		if (mergeContext.isSkeletonMergeEnabled()) {
			ResourceContext resourceContext = new TransientResourceContext();
			resourceContext.setCheckoutFilesEnabled(true);
			resourceContext.setCreateFoldersEnabled(true);
			resourceContext.setOverwriteFilesEnabled(true);
			for (int i = 0; i < size; i++) {
				String mergedContent = null;
				JMerger jMerger = null;
				IFile file = null;
				InputStream inStream = null;
				byte[] buf = null;
				
				jMerger = mergeModels[i];
				file = workspaceFiles[i];
				if (file != null && jMerger != null && file.exists()) {  
					// a JMerger model of the file exists, merge the contents
					try {
						inStream = file.getContents();
						jMerger.setSourceCompilationUnit(jMerger.createCompilationUnitForInputStream(inStream));
						jMerger.merge();
						mergedContent = jMerger.getTargetCompilationUnitContents();	
						if (mergedContent != null) {
							try {
								buf = mergedContent.getBytes(file.getCharset());
							} catch (UnsupportedEncodingException e) {
								buf = mergedContent.getBytes();
							}
							inStream = new ByteArrayInputStream(buf);
							IPath targetPath = file.getLocation();
							if (targetPath != null) {
								FileResourceUtils.createFileAtLocation(resourceContext, targetPath.makeAbsolute(), inStream,
									  monitor, statusHandler);
							}
						}
					} catch (CoreException e) {
						status = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_FILE_MERGE, file), e);
					} finally {
						try {
							if (inStream != null) {
								inStream.close();
							}
						} catch (IOException e) {
							// ignore exceptions in closing file
						}
					}
				}
			}
			
		}
		return status;
	}
	
}

Back to the top