blob: 97791b8644cf1a562123a922cf1cac6472826b00 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.jsdt.internal.ui.propertiesfileeditor;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.StringCharacterIterator;
import java.util.Properties;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Properties key hyperlink detector.
* <p>
* XXX: This does not work for properties files coming from a JAR due to
* missing J Core functionality. For details see:
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=22376
* </p>
*
* @since 3.1
*/
public class PropertyKeyHyperlinkDetector extends AbstractHyperlinkDetector {
/*
* @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion, boolean)
*/
public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
ITextEditor textEditor= (ITextEditor)getAdapter(ITextEditor.class);
if (region == null || textEditor == null || canShowMultipleHyperlinks)
return null;
IEditorSite site= textEditor.getEditorSite();
if (site == null)
return null;
int offset= region.getOffset();
if (!checkEnabled(textEditor, offset))
return null;
ITypedRegion partition= null;
try {
IStorageEditorInput storageEditorInput= (IStorageEditorInput)textEditor.getEditorInput();
IDocument document= textEditor.getDocumentProvider().getDocument(storageEditorInput);
if (document instanceof IDocumentExtension3)
partition= ((IDocumentExtension3)document).getPartition(IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING, offset, false);
// Check whether it is the correct partition
if (partition == null || !IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) {
return null;
}
// Check whether the partition covers the selection
if (offset + region.getLength() > partition.getOffset() + partition.getLength()) {
return null;
}
// Extract the key from the partition (which contains key and assignment
String key= document.get(partition.getOffset(), partition.getLength());
String realKey= key.trim();
int delta= key.indexOf(realKey);
String unicodeKey= getUnicodeString(realKey);
// Check whether the key is valid
Properties properties= new Properties();
properties.load(new ByteArrayInputStream(document.get().getBytes()));
if (properties.getProperty(unicodeKey) == null) {
return null;
}
return new PropertyKeyHyperlink[] {new PropertyKeyHyperlink(new Region(partition.getOffset() + delta, realKey.length()), realKey, textEditor)};
} catch (BadLocationException ex) {
return null;
} catch (BadPartitioningException ex) {
return null;
} catch (IOException ex) {
return null;
}
}
private String getUnicodeString(String key) {
StringCharacterIterator iter= new StringCharacterIterator(key);
StringBuffer result= new StringBuffer();
while (iter.getIndex() < iter.getEndIndex()) {
char c= iter.current();
if (c == '\\') {
iter.next();
c= iter.current();
if (c == 'u') {
StringBuffer unicode= new StringBuffer();
unicode.append(iter.next());
unicode.append(iter.next());
unicode.append(iter.next());
unicode.append(iter.next());
c= (char)Integer.parseInt(unicode.toString(), 16);
}
}
result.append(c);
iter.next();
}
return result.toString();
}
private boolean checkEnabled(ITextEditor textEditor, int offset) {
if (offset < 0)
return false;
// XXX: Must be changed to IStorageEditorInput once support for JARs is available (see class Javadoc for details)
return textEditor.getEditorInput() instanceof IFileEditorInput;
}
}