Eclipseplugins
UserExitFileGenerator.java
1 package com.proalpha.pds.generator;
2 
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileReader;
6 import java.io.IOException;
7 import java.nio.file.Path;
8 import java.nio.file.Paths;
9 import java.util.List;
10 import java.util.Set;
11 import java.util.TreeSet;
12 import java.util.regex.Matcher;
13 import java.util.regex.Pattern;
14 
15 import javax.xml.bind.JAXBException;
16 
17 import org.apache.commons.io.FileUtils;
18 import org.apache.commons.io.LineIterator;
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.runtime.NullProgressMonitor;
21 import org.eclipse.core.runtime.jobs.IJobManager;
22 import org.eclipse.core.runtime.jobs.Job;
23 import org.eclipse.jface.dialogs.MessageDialog;
24 import org.eclipse.swt.widgets.Display;
25 
26 import com.proalpha.pds.paconnector.userexit.UserExitDelegate;
27 import com.proalpha.pds.paconnector.userexit.UserExitInclude;
28 import com.proalpha.pds.templates.data.IGeneratorDataContainer;
29 import com.proalpha.pds.templates.helper.IDEUtils;
30 import com.proalpha.pds.templates.jaxb.JaxUnmarshallerGeneric;
31 import com.proalpha.pds.templates.jaxb.TtUserExits;
32 import com.proalpha.pds.templates.jaxb.TtUserExits.TtUserExitsRow;
33 import com.proalpha.pds.templates.jet.IpaTemplateGenerator;
34 import com.proalpha.pds.templates.jet.JetTemplateFactory;
35 
62 public class UserExitFileGenerator {
63 
64  private static final String TEMPLATE_GENERATOR = "pAUserExitIncludeFile";
65 
66  private List<TtUserExitsRow> definedUserExits;
67 
68  private final IGeneratorDataContainer dataContrainer;
69 
70  private final UserExitDelegate userExitDelegate;
71 
81  public UserExitFileGenerator(IGeneratorDataContainer dataContainer, UserExitDelegate userExitDelegate)
82  throws Exception {
83 
84  this.dataContrainer = dataContainer;
85  this.userExitDelegate = userExitDelegate;
86 
87  initializeGenerator();
88 
89  }
90 
102  private void initializeGenerator() throws Exception {
103 
104  String fileName = dataContrainer.getFileName();
105  String customLevel = dataContrainer.getCustomLevel();
106  String parentObject = dataContrainer.getParentObject();
107  String xBaseName = calculateXBaseName(fileName, customLevel);
108 
109  dataContrainer.setFileName(xBaseName);
110 
111  String description = String.format("UserExits in %s %s %s", parentObject,
112  System.getProperties().getProperty("line.separator"), dataContrainer.getObjectInfo());
113 
114  dataContrainer.setDescription(description);
115 
116  String userExitSortCase = dataContrainer.getSortCase();
117  UserExitInclude userExitInclude = userExitDelegate.getEmptyUserExitInclude();
118 
119  userExitInclude.setName(xBaseName);
120  userExitInclude.setIncludeType(customLevel + "X");
121  userExitInclude.setSourceFileName(parentObject);
122  userExitInclude.setSortCase(userExitSortCase);
123  File userExitXMLFile = userExitDelegate.extractUserExitToXMLFile(userExitInclude);
124  // check the return value of pA User Exit Generator. If empty no UE is generated
125  if (!userExitXMLFile.toString().equals("")) {
126  definedUserExits = readUserExitFormStandardFile(userExitXMLFile);
127  dataContrainer.setUserExits(definedUserExits);
128 
129  } else {
130  throw new JAXBException("No User Exits generated for : " + userExitInclude.getSourceFileName());
131  }
132 
133  definedUserExits = readUserExitFormStandardFile(userExitXMLFile);
134  dataContrainer.setUserExits(definedUserExits);
135 
136  }
137 
138  private String calculateXBaseName(String fileName, String customLevel) throws Exception {
139 
140  if (fileName.contains(".")) {
141 
142  return fileName.substring(0, fileName.lastIndexOf('.')) + getFileExtension(fileName, customLevel);
143 
144  } else {
145  throw new Exception("Could not calculate XBaseName, invalid filename " + fileName);
146  }
147 
148  }
149 
158  private String getFileExtension(String fileName, String customLevel) throws Exception {
159  String fileExtension = "";
160 
161  if (fileName.endsWith(".p")) {
162  fileExtension = "." + customLevel.toLowerCase() + "xp";
163  } else if (fileName.endsWith(".w")) {
164  fileExtension = "." + customLevel.toLowerCase() + "xw";
165  } else if (fileName.endsWith(".lib")) {
166  fileExtension = "." + customLevel.toLowerCase() + "xl";
167  } else if (fileName.endsWith(".if") || fileName.endsWith(".i")) {
168  fileExtension = "." + customLevel.toLowerCase() + "xi";
169  } else if (fileName.endsWith(".tdf")) {
170  fileExtension = "." + customLevel.toLowerCase() + "xt";
171  } else if (fileName.endsWith(".pds")) {
172  fileExtension = "." + customLevel.toLowerCase() + "xp";
173  } else if (fileName.endsWith(".fld")) {
174  fileExtension = "." + customLevel.toLowerCase() + "xf";
175  } else if (fileName.endsWith(".cdf")) {
176  fileExtension = "." + customLevel.toLowerCase() + "xc";
177  }
178 
179  if (fileExtension.isEmpty()) {
180  throw new Exception("Could not calculate file extension for file " + fileName);
181  }
182 
183  return fileExtension;
184  }
185 
193  private List<TtUserExitsRow> readUserExitFormStandardFile(File userExitXMLFile) throws JAXBException {
194 
195  if (!userExitXMLFile.exists()) {
196  throw new JAXBException("No UserExits Info file from proALPHA generated");
197  }
198  JaxUnmarshallerGeneric<TtUserExits> jaxb = new JaxUnmarshallerGeneric<>(TtUserExits.class);
199 
200  TtUserExits userExits = jaxb.readXMLFile(userExitXMLFile);
201 
202  if (userExits == null) {
203  throw new JAXBException("Error Reading XML File " + userExitXMLFile.getAbsolutePath());
204  }
205 
206  return userExits.getTtUserExitsRow();
207 
208  }
209 
220  public void generate() throws Exception {
221 
222  String workdir = dataContrainer.getStarparameterReader().getWorkingDirectory().getRawLocation().toString();
223 
224  Path fullFilePath = Paths.get(workdir, dataContrainer.getRelativePath(), dataContrainer.getFileName());
225 
226  if (isUserExitIncludeNew(fullFilePath.toAbsolutePath().toString())) {
227  createNewUserExitInclude();
228  } else {
229  refreshUserExitInclude();
230 
231  }
232 
233  }
234 
235  private boolean isUserExitIncludeNew(String fileName) {
236  File f = new File(fileName);
237  return (!f.exists() && !f.isDirectory());
238  }
239 
246  public void generateUserExitClassAndBalpEntry() throws Exception {
247 
248  generate();
249  GeneratorFactory generatorFactory = new GeneratorFactory();
250  generatorFactory.createBalpGenerator(dataContrainer).generate();
251 
252  }
253 
254  private void refreshUserExitInclude() throws Exception {
255 
256  if (confirmRefresh()) {
257 
258  File userExitIncludeFile = dataContrainer.getOutputFile().getLocation().toFile();
259  // read in old user exit
260  Set<String> availableUserExits = readUserExitsFormIncludeFile(userExitIncludeFile);
261 
262  Set<String> oldUserExits = new TreeSet<>();
263  Set<String> specialUserExits = new TreeSet<>();
264 
265  for (TtUserExitsRow row : definedUserExits) {
266  oldUserExits.add(row.getUserExitName().toUpperCase());
267  if (row.isIsSpecialUserExit()) {
268  specialUserExits.add(row.getUserExitName().toUpperCase());
269  }
270  }
271 
272  // newUserExits = definedUserExit - availableUserExits
273  Set<String> newUserExits = new TreeSet<>(oldUserExits);
274  newUserExits.removeAll(availableUserExits);
275  newUserExits.removeAll(specialUserExits);
276 
277  // removedUserExits = availabelUserExits - definedUserExits
278  Set<String> removedUserExits = new TreeSet<>(availableUserExits);
279  removedUserExits.removeAll(oldUserExits);
280 
281  writeUserExitsInclude(dataContrainer.getOutputFile(), newUserExits);
282 
283  if (!newUserExits.isEmpty()) {
284  displayMessageBox("Exits " + newUserExits.toString() + " added.");
285  }
286 
287  if (!removedUserExits.isEmpty()) {
288  displayMessageBox("Exits " + removedUserExits.toString() + " removed.");
289  }
290  if (newUserExits.isEmpty() && removedUserExits.isEmpty()) {
291  displayMessageBox("File " + userExitIncludeFile.getName() + " \nis already up to Date.");
292  }
293  }
294 
295  }
296 
297  private void displayMessageBox(String message) {
298  MessageDialog.openInformation(Display.getCurrent().getActiveShell(), "Refresh UserExit Include", message);
299 
300  }
301 
302  private void writeUserExitsInclude(IFile outputFile, Set<String> newUserExits) throws Exception {
303 
304  File includeFile = dataContrainer.getOutputFile().getLocation().toFile();
305  String line = null;
306  StringBuilder outputBuilder = new StringBuilder();
307  Integer insertOffset = -1;
308  String lineSeparator = System.getProperty("line.separator");
309 
310  try (BufferedReader reader = new BufferedReader(new FileReader(includeFile))) {
311  while ((line = reader.readLine()) != null) {
312  if (!isUserExitDefinition(line))
313  outputBuilder.append(line + lineSeparator);
314  else if (insertOffset < 0)
315  insertOffset = outputBuilder.length();
316  }
317  }
318 
319  if (insertOffset > 0) {
320  IpaTemplateGenerator paUserExitDefinitins = JetTemplateFactory
321  .getFactoryInstance(dataContrainer.getVersion()).getTemplate("paUserExitDefinitions");
322 
323  String generatetUserExits = paUserExitDefinitins.generate(dataContrainer.getDataAsMap());
324 
325  outputBuilder.insert(insertOffset, generatetUserExits + lineSeparator);
326  }
327 
328  insertOffset = outputBuilder.lastIndexOf("/* _UIB-CODE-BLOCK-END */");
329 
330  String outputString = "";
331 
332  for (String newUserExit : newUserExits) {
333 
334  String beginDef = String.format("&IF DEFINED(%s) = 2 &THEN", newUserExit.toUpperCase()) + lineSeparator;
335  String endDef = String.format("&ENDIF /* %s */", newUserExit.toUpperCase()) + lineSeparator;
336 
337  outputString = outputString + beginDef + lineSeparator + endDef + lineSeparator;
338  }
339 
340  outputBuilder.insert(insertOffset, outputString);
341 
342  new ContentWriter(includeFile, outputBuilder.toString()).writeContentToHarddisk();
343 
344  IDEUtils.openFileInEditor(new NullProgressMonitor(), outputFile);
345 
346  }
347 
348  private boolean isUserExitDefinition(String line) {
349 
350  Pattern pattern = Pattern.compile("(?i)\\s*&GLOB \\{&PA-X.*BASISNAME\\}_.*");
351 
352  Matcher m = pattern.matcher(line);
353 
354  return (m.matches());
355 
356  }
357 
358  private Set<String> readUserExitsFormIncludeFile(File includeFile) throws IOException {
359  Set<String> resultSet = new TreeSet<>();
360 
361  LineIterator iterator = FileUtils.lineIterator(includeFile);
362  try {
363 
364  while (iterator.hasNext()) {
365  String line = iterator.nextLine();
366 
367  if (isUserExitDefinition(line)) {
368 
369  String tempStr = line.replaceAll("\\s*&GLOB \\{&PA-X.*BASISNAME\\}_", "");
370  String userExitName = tempStr.substring(0, tempStr.indexOf(' ')).toUpperCase();
371 
372  resultSet.add(userExitName);
373  }
374  }
375  } finally {
376  LineIterator.closeQuietly(iterator);
377  }
378 
379  return resultSet;
380  }
381 
382  private boolean confirmRefresh() {
383 
384  return dataContrainer.isGenerationConfirmed();
385 
386  }
387 
388  private void createNewUserExitInclude() throws Exception {
389 
390  new ContentGenerator("UserExit Generator", dataContrainer, TEMPLATE_GENERATOR).schedule();
391 
392  IJobManager jobManager = Job.getJobManager();
393  jobManager.join(ContentGenerator.JOB_FAMILY, new NullProgressMonitor());
394 
395  }
396 
397 }
UserExitFileGenerator(IGeneratorDataContainer dataContainer, UserExitDelegate userExitDelegate)
File extractUserExitToXMLFile(UserExitInclude userExitInclude)
abstract void setIncludeType(String includeType)
abstract void setSourceFileName(String sourceFileName)