/* * Copyright 2010 Red Hat, Inc. and/or its affiliates. * * Licensed 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.drools.eclipse.refactoring; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.drools.compiler.compiler.DroolsParserException; import org.drools.eclipse.DRLInfo; import org.drools.eclipse.DRLInfo.PatternInfo; import org.drools.eclipse.DroolsEclipsePlugin; import org.drools.compiler.lang.descr.ImportDescr; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.internal.corext.refactoring.rename.JavaRenameProcessor; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.CompositeChange; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.TextFileChange; import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import org.kie.eclipse.utils.FileUtils; /** * Participant to generate refactoring when a type is renamed. */ @SuppressWarnings("restriction") public class RuleIFileRenameParticipant extends RenameParticipant { public static final String NAME = "Rule File Rename Refactoring"; private DRLProjectDetector drlProjectDetector = new DRLProjectDetector(); private RefactoringProcessor processor; private List<IFile> drlFiles; private IFile file; private String newName; private String currentName; private String packageName; private String className; private Pattern classPattern; @Override public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException { RefactoringStatus status = new RefactoringStatus(); if (file==null || file.isReadOnly()) status.addFatalError("File don't exists or is read only"); return status; } @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { CompositeChange changes = new CompositeChange("Reorganize DRL " + currentName + " Type "); drlFiles = drlProjectDetector.detect(file.getProject()); classPattern = Pattern.compile("(?<=\\W)" + currentName + "(?=\\W)"); for (IFile drlFile : drlFiles) { TextFileChange change = createChangesForFile(drlFile); if ( change != null && change.getEdit().getChildrenSize() > 0 ) { changes.add(change); } } if (changes.getChildren().length == 0) { return null; } DroolsEclipsePlugin.getDefault().setForceFullBuild(); return changes; } private TextFileChange createChangesForFile(IFile drlFile) throws CoreException { DRLInfo drlInfo = null; try { drlInfo = DroolsEclipsePlugin.getDefault().parseResource( drlFile, false ); } catch (DroolsParserException e) { } if ( drlInfo == null ) { return null; } String content = FileUtils.readFile(drlFile); if ( content == null ) { return null; } TextFileChange change = new TextFileChange(drlFile.getName(), drlFile); MultiTextEdit mte = new MultiTextEdit(); change.setEdit(mte); boolean isImported = false; for (ImportDescr importDescr : drlInfo.getPackageDescr().getImports()) { isImported |= importDescr.getTarget().equals(className) || importDescr.getTarget().equals(packageName + ".*"); addReplace(mte, importDescr.getTarget(), content, importDescr.getStartCharacter(), importDescr.getEndCharacter()); } if (!isImported) { return change; } for (DRLInfo.RuleInfo ruleInfo : drlInfo.getRuleInfos()) { List<PatternInfo> patternInfos = ruleInfo.getPatternInfos(); if (patternInfos != null) { for (DRLInfo.PatternInfo patternInfo : patternInfos) { addReplace(mte, patternInfo.getPatternTypeName(), content, patternInfo.getStart(), patternInfo.getEnd()); } addReplace(mte, className, content, ruleInfo.getConsequenceStart(), ruleInfo.getConsequenceEnd()); } else { addReplace(mte, className, content, ruleInfo.getRuleStart(), ruleInfo.getRuleEnd()); } } for (DRLInfo.FunctionInfo functionInfo : drlInfo.getFunctionInfos()) { addReplace(mte, className, content, functionInfo.getFunctionStart(), functionInfo.getFunctionEnd()); } return change; } private void addReplace(MultiTextEdit mte, String descrClassName, String content, int start, int end) { if (className.equals(descrClassName)) { String text = content.substring(start-1, end+1); Matcher matcher = classPattern.matcher(text); while (matcher.find()) { mte.addChild(new ReplaceEdit(matcher.start() + start - 1, currentName.length(), newName)); } } } @Override public String getName() { return NAME; } @Override protected boolean initialize(Object element) { if (element instanceof IFile) { IFile file = (IFile)element; if (file.getType()==IFile.FILE) { if (file.getFileExtension() != null && file.getFileExtension().equalsIgnoreCase("java")) { this.processor = getProcessor(); this.file = file; if (this.processor instanceof JavaRenameProcessor) { JavaRenameProcessor javaProcessor = (JavaRenameProcessor)processor; newName = javaProcessor.getNewElementName().replace(".java", ""); currentName = javaProcessor.getCurrentElementName(); try { ICompilationUnit compilationUnit = (ICompilationUnit)javaProcessor.getElements()[0]; packageName = compilationUnit.getPackageDeclarations()[0].getElementName(); className = packageName + "." + currentName; } catch (Exception e) { return false; } return true; } } } } return false; } }