/*
* 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.apache.directory.studio.templateeditor.editor.widgets;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.directory.studio.entryeditors.IEntryEditor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.apache.directory.studio.templateeditor.EntryTemplatePluginUtils;
import org.apache.directory.studio.templateeditor.model.widgets.TemplateLink;
/**
* This class implements an editor link.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class EditorLink extends EditorWidget<TemplateLink>
{
/** The Regex for matching an URL */
private static final String REGEX_URL = "([a-zA-Z][a-zA-Z0-9+-.]*:[^\\s]+)"; //$NON-NLS-1$
/** The Regex for matching an email address*/
private static final String REGEX_EMAIL_ADDRESS = "([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4})"; //$NON-NLS-1$
/** The link widget */
private Link link;
/**
* Creates a new instance of EditorLink.
*
* @param editor
* the associated editor
* @param templateLink
* the associated template link
* @param toolkit
* the associated toolkit
*/
public EditorLink( IEntryEditor editor, TemplateLink templateLink, FormToolkit toolkit )
{
super( templateLink, editor, toolkit );
}
/**
* {@inheritDoc}
*/
public Composite createWidget( Composite parent )
{
// Creating and initializing the widget UI
Composite composite = initWidget( parent );
// Updating the widget's content
updateWidget();
// Adding the listeners
addListeners();
return composite;
}
/**
* Creates and initializes the widget UI.
*
* @param parent
* the parent composite
* @return
* the associated composite
*/
private Composite initWidget( Composite parent )
{
// Creating the link widget
link = new Link( parent, SWT.NONE );
link.setLayoutData( getGridata() );
return parent;
}
/**
* Updates the widget's content.
*/
private void updateWidget()
{
// Checking is we need to display a value taken from the entry
// or use the given value
String attributeType = getWidget().getAttributeType();
if ( attributeType != null )
{
link.setText( addLinksTags( EditorWidgetUtils.getConcatenatedValues( getEntry(), attributeType ) ) );
}
else
{
link.setText( addLinksTags( getWidget().getValue() ) );
}
}
/**
* Adds the listeners.
*/
private void addListeners()
{
link.addListener( SWT.Selection, new Listener()
{
public void handleEvent( Event event )
{
// Creating the URL
String url = null;
// Getting the text that was clicked
String text = event.text;
if ( isUrl( text ) )
{
url = text;
}
else if ( isEmailAddress( text ) )
{
url = "mailto:" + text; //$NON-NLS-1$
}
if ( url != null )
{
try
{
PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL( new URL( url ) );
}
catch ( Exception e )
{
// Logging the error
EntryTemplatePluginUtils.logError( e, "An error occurred while opening the link.", //$NON-NLS-1$
new Object[0] );
// Launching an error dialog
MessageDialog
.openError(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
Messages.getString( "EditorLink.ErrorMessageDialogTitle" ), Messages.getString( "EditorLink.ErrorMessageDialogMessage" ) ); //$NON-NLS-1$ //$NON-NLS-2$
}
}
else
{
// Logging the error
EntryTemplatePluginUtils.logError( null, "An error occurred while opening the link. URL is null.", //$NON-NLS-1$
new Object[0] );
// Launching an error dialog
MessageDialog
.openError(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
Messages.getString( "EditorLink.ErrorMessageDialogTitle" ), Messages.getString( "EditorLink.ErrorMessageDialogMessage" ) ); //$NON-NLS-1$ //$NON-NLS-2$
}
}
} );
}
/**
* Adds link tags (<a>link</a>) to the links (URLs and email
* addresses) found in the given string.
*
* @param s
* the string
* @return
* the string in which links have been added
*/
private static String addLinksTags( String s )
{
List<String> links = new ArrayList<String>();
// Getting the URLs
links.addAll( Arrays.asList( getUrls( s ) ) );
// Getting the email addresses
links.addAll( Arrays.asList( getEmailAddresses( s ) ) );
// Creating the final string
StringBuilder sb = new StringBuilder();
try
{
// Inserting link tags
int start = 0;
for ( String link : links )
{
int indexOfLink = s.indexOf( link );
sb.append( s.subSequence( start, indexOfLink ) );
sb.append( "<a>" ); //$NON-NLS-1$
sb.append( link );
sb.append( "</a>" ); //$NON-NLS-1$
start = indexOfLink + link.length();
}
sb.append( s.substring( start, s.length() ) );
}
catch ( StringIndexOutOfBoundsException e )
{
// In case we hit a wrong index, we fail gracefully by
// returning the original string
return s;
}
// Returning the final string
return sb.toString();
}
/**
* Get the urls contained in the email address.
*
* @param s
* the string
* @return
* an array containing the urls found in the given string
*/
private static String[] getUrls( String s )
{
return getMatchingStrings( s, Pattern.compile( REGEX_URL + ".*" ) ); //$NON-NLS-1$
}
/**
* Get the email addresses contained in the email address.
*
* @param s
* the string
* @return
* an array containing the email addresses found in the given string
*/
private static String[] getEmailAddresses( String s )
{
return getMatchingStrings( s, Pattern.compile( REGEX_EMAIL_ADDRESS + ".*" ) ); //$NON-NLS-1$
}
/**
* Get the matching strings contained in a string using a pattern.
*
* @param s
* the string
* @param p
* the pattern
* @return
* an array containing the matching strings found in the given string
*/
private static String[] getMatchingStrings( String s, Pattern p )
{
List<String> matchingStrings = new ArrayList<String>();
while ( s.length() > 0 )
{
Matcher m = p.matcher( s );
if ( m.matches() )
{
String link = m.group( 1 );
matchingStrings.add( link );
s = s.substring( link.length() );
}
else
{
s = s.substring( 1 );
}
}
return matchingStrings.toArray( new String[0] );
}
/**
* Indicates if the given string is a URL.
*
* @param s
* the string
* @return
* <code>true</code> if the given string is a URL,
* <code>false</code> if not.
*/
private boolean isUrl( String s )
{
return Pattern.matches( REGEX_URL, s );
}
/**
* Indicates if the given string is an email address.
*
* @param s
* the string
* @return
* <code>true</code> if the given string is an email address,
* <code>false</code> if not.
*/
private boolean isEmailAddress( String s )
{
return Pattern.matches( REGEX_EMAIL_ADDRESS, s );
}
/**
* {@inheritDoc}
*/
public void update()
{
updateWidget();
}
/**
* {@inheritDoc}
*/
public void dispose()
{
// Nothing to do
}
}