blob: 290b04545dd80bede74e68621f52312152e93e5d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.netbeans.modules.web.refactoring;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JEditorPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import org.netbeans.editor.BaseDocument;
import org.openide.loaders.DataObject;
import org.openide.text.CloneableEditorSupport;
import org.openide.text.PositionBounds;
import javax.swing.text.Position.Bias;
import org.openide.nodes.Node;
import org.openide.text.PositionRef;
import org.openide.util.Exceptions;
import org.openide.util.Parameters;
/**
* Resolves position bounds of an element that is being refactored. If the
* <code>elementName</code> is null or no matching string can be found in the data
* object, returns <code>PositionBounds</code> that represents the beginning of the file.
*
* @author Erno Mononen
*/
// TODO: Copied from jpa/refactoring.
public class PositionBoundsResolver {
/**
* The data object that is being refactored.
*/
private final DataObject dataObject;
/**
* The editor support associated with the data object.
*/
private final CloneableEditorSupport editorSupport;
/**
* Name of the element that is being refactored. If the element represents class,
* it should be its fully qualified name.
*/
private final String elementName;
/**
* Creates a new resolver for the given <code>dataObject</code>.
* @param dataObject the data object that is being refactored. Must have an
* associated <code>CloneableEditorSupport</code> and must not be null.
* @param elementName the element that is being refactored. If the element represents class,
* it should be its fully qualified name. If a <code>null</code> is given, {@link #getPositionBounds}
* returns PositionBounds that represents the beginning of the file.
* @throws IllegalArgumentException if the given <code>dataObject</code> was null
* or if didn't have CloneableEditorSupport associated.
*/
public PositionBoundsResolver(DataObject dataObject, String elementName) {
Parameters.notNull("dataObject", dataObject);
this.dataObject = dataObject;
this.editorSupport = findCloneableEditorSupport();
if (this.editorSupport == null){
throw new IllegalArgumentException("Couldn't get CloneableEditorSupport for " + dataObject); //NO18N
}
this.elementName = elementName;
}
/**
*@return PositionBounds representing the position of the name of the entity that is being
* refactored or PostionBounds representing the start of the file if the position
* of the entity could not be resolved.
*/
public PositionBounds getPositionBounds(){
if (elementName != null){
try {
BaseDocument doc = getDocument();
String text = doc.getText(0, doc.getLength());
int offset = text.indexOf(elementName);
if (offset > -1){
PositionRef start = editorSupport.createPositionRef(offset, Bias.Forward);
PositionRef end = editorSupport.createPositionRef(offset + elementName.length(), Bias.Backward);
return new PositionBounds(start, end);
}
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}
}
return getDefaultPositionBounds();
}
/**
* @return PositionBounds representing the beginning of the file associated
* with the <code>dataObject</code>.
*/
private PositionBounds getDefaultPositionBounds(){
PositionRef start = editorSupport.createPositionRef(0, Bias.Forward);
PositionRef end = editorSupport.createPositionRef(0, Bias.Backward);
return new PositionBounds(start, end);
}
// adapted from JSFEditorUtilities
private CloneableEditorSupport findCloneableEditorSupport() {
Node.Cookie obj = dataObject.getCookie(org.openide.cookies.OpenCookie.class);
if (obj instanceof CloneableEditorSupport) {
return (CloneableEditorSupport)obj;
}
obj = dataObject.getCookie(org.openide.cookies.EditorCookie.class);
if (obj instanceof CloneableEditorSupport) {
return (CloneableEditorSupport)obj;
}
return null;
}
/**
* @return the BaseDocument representing contents of our <code>dataObject</code>.
*/
private BaseDocument getDocument(){
BaseDocument result = (BaseDocument) editorSupport.getDocument();
// editor was not opened
if (result == null) {
final CreateXMLPane runnable = new CreateXMLPane();
try {
if (SwingUtilities.isEventDispatchThread()){
runnable.run();
} else {
SwingUtilities.invokeAndWait(runnable);
}
result = new BaseDocument(runnable.getPane().getEditorKit().getClass(), false);
String text= readResource(dataObject.getPrimaryFile().getInputStream());
result.remove(0, result.getLength());
result.insertString(0, text, null);
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
} catch (InvocationTargetException ex) {
Exceptions.printStackTrace(ex);
} catch (FileNotFoundException ex) {
Exceptions.printStackTrace(ex);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}
}
return result;
}
/**
* Reads the given stream.
*/
private String readResource(InputStream stream){
StringBuffer result = new StringBuffer();
String lineSep = System.getProperty("line.separator");//NO18N
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));//NO18N
String line = reader.readLine();
while (line != null) {
result.append(line);
result.append(lineSep);
line = reader.readLine();
}
} catch (UnsupportedEncodingException ex) {
Exceptions.printStackTrace(ex);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
} finally {
try {
if (reader != null){
reader.close();
}
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}
return result.toString();
}
// copied from JSFFrameworkProvider
private static class CreateXMLPane implements Runnable{
JEditorPane pane;
public void run(){
pane = new JEditorPane("text/xml", "");
}
public JEditorPane getPane(){
return pane;
}
}
}