?? htmltemplatedisplay.java
字號:
package com.ca.directory.jxplorer.viewer;
import com.ca.commons.cbutil.*;
import com.ca.commons.naming.*;
import com.ca.directory.jxplorer.*;
import com.ca.directory.jxplorer.tree.SmartTree;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.zip.ZipException;
/**
* Display Template handles the insertion of attribute values into
* an HTML template, in order to display filtered information to
* the user in an attractive manner.<p>
*
* It also implements a simple web browser for viewing help links
* etc.<p>
*
* Form submission is done in the @MyHTMLEditorKit class.
*/
/* IMPLEMENTATION NOTES....
*
* This is a large class, and should probably be broken up - an MVC model maybe, but
* at least separate the functionality families.
*
* It is currently doing three separate things.
* A) Operating the Template Display GUI
* B) Keeping track of the html templates on disk, and indexing them by object class
* C) Parsing the html text and doing tricks (many of which may not be necessary, since they were often
* work arounds for buggy sun code in the good 'ol days).
*/
public class HTMLTemplateDisplay extends JPanel
implements DataSink, PluggableEditor
{
JScrollPane scrollDisplay;
DataSource currentDataSource = null;
JEditorPane editor;
JViewport viewport; // was CBViewport
JTextArea bloop;
String baseText; // the original text, formatted for html but without attribute values
StringBuffer htmlText; // the display text, including attributes...
// String baseURL; // the base file URL of the template directory location
// String localURL; //TE: the path to the users working dir. Used to store the temporary templates extracted from a zip/jar.
// URL base = null; // the same base file URL, as a url.
Component display; // a display panel used for user error messages.
public static final String DEFAULTTEXT = "<html><head><title>Default Template</title></head><body> <dxtemplate:get-all-attributes> <br> </body></html>";
public static final String ATTRIBTAG = "<dxtemplate:";
public static String NOVALUEFOUND;
public static final String JPEGEXTENSION = ".jpg"; //TE: the extenion of the temporary jpegPhotos stored locally.
public static final String DOCEXTENSION = ".doc"; //TE: the extenion of the temporary documents stored locally.
public static final String XLSEXTENSION = ".xls"; //TE: the extenion of the temporary spreadsheets stored locally.
public static final String WAVEXTENSION = ".wav"; //TE: the extenion of the temporary wav files stored locally.
public static final String AVIEXTENSION = ".avi"; //TE: the extenion of the temporary avi files stored locally.
public static final String MIDEXTENSION = ".mid"; //TE: the extenion of the temporary mid files stored locally.
public static final String startFile = "start"; // the initially displayed html page
public static final int MAX_LEGAL_VALUE_LENGTH = 500;
public static final String ILLEGAL_VALUE = "[ATTRIBUTE TOO LARGE TO DISPLAY]";
public static final String DEFAULT = "defaulttemplate"; // name for default templates...
Properties myProperties; // contains info about default urls and file locations.
JToolBar toolBar; // the toolbar containing the list of allowed templates
/*
* A bunch of variables are needed to keep track of all the available html templates,
* and the users state when viewing a particular template combination.
*/
// The combo box the user uses to select a display template
CBJComboBox viewTemplates;
// The position in the combo box for a particular 'object class set signature' (i.e. what the user last
// viewed for a particular object class set). Keyed by object class signature.
Hashtable viewTemplatesPos = new Hashtable(); // hashtable of most-recently-used templates
// All available templates (as File objects, keyed by lower case object class. Defaults keyed by empty string "").
Hashtable templates = new Hashtable(100);
// the 'object class signature' (the object classes for a particular entry concatenated to a unique key)
String oldObjectClassesSignature = "";
// the base directory for all the html templates
File baseTemplateDir;
// the base directory for any plugin html templates
File pluginTemplateDirectory = null;
// String currentLDAPObjectClass = ""; // the current object class being viewed
DXEntry currentEntry = null; // the current entry being displayed.
// (we need to remember this, because the display template changes)
static String currentTemplateName = ""; // the name of the currently selected template...
public static String NODATA; // no data html page - not static, 'cause of internationalisation requirements...
public boolean showHTMLErrors = true; // for debugging html forms.
protected MyHyperlinkListener hyperlinkListener;
protected MyHTMLEditorKit htmlEditorKit;
protected boolean settingUpTemplates = false; // utility variable to disable combo box action listener during combo box setup.
Vector currentBinaryAttributes = new Vector(0); // used by MyHTMLEditorKit to flag special data...
CBResourceLoader resourceLoader = null; // used to load HTML templates from zip/jar files.
protected String currentDN; //TE: part of the name of the temporary files that are created for jpegPhoto & audio attributes (i.e. the dn of the entry).
SmartTree smartTree = null;
private static Logger log = Logger.getLogger(HTMLTemplateDisplay.class.getName());
/**
* Default Constructor for HTMLTemplateDisplay
*/
public HTMLTemplateDisplay(Component owner, Properties props, CBResourceLoader resourceLoader)
{
commonConstructorCode(owner, props, resourceLoader);
setToDefault();
}
protected void setToDefault()
{
htmlText = new StringBuffer(DEFAULTTEXT);
baseText = new String(DEFAULTTEXT);
}
/**
* <p>A bunch of vaguely hacky code to add hyperlink-like functionality to the html display</p>
*/
class MyHyperlinkListener implements HyperlinkListener
{
public void hyperlinkUpdate(final HyperlinkEvent e)
{
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
String desc = e.getDescription();
if (desc.toLowerCase().startsWith("dn:")) // el hack especial
{
String dn = desc.substring(desc.indexOf(":") + 1);
if (smartTree != null)
{
smartTree.readAndExpandDN(new DN(dn));
}
}
else if (desc.toLowerCase().startsWith(".." + File.separator + "temp" + File.separator + "audio" + File.separator) || desc.toLowerCase().startsWith(".." + File.separator + ".." + File.separator + "temp" + File.separator + "audio" + File.separator)) //TE: audio handler.
{//TE: launches audio files...
if (!System.getProperty("os.name").equalsIgnoreCase("SunOS")) //TE: Check if the operating system is Sun if so don't attempt to play the audio file.
{
String path = CBCache.getAudioDirPath();
String audioFilePath = desc.substring(desc.indexOf("temp", desc.lastIndexOf("\"")));
String audioFileName = audioFilePath.substring(audioFilePath.lastIndexOf("\\"));
String extension = audioFileName.substring(audioFileName.indexOf("."));
if (extension.equalsIgnoreCase(".xxx"))
CBUtility.error(CBIntText.get("Unable to play unknown audio file type"));
else
CBLauncher.launchProgram(extension, path + audioFileName);
}
}
else if (desc.toLowerCase().startsWith(".." + File.separator + "temp" + File.separator) || desc.toLowerCase().startsWith(".." + File.separator + ".." + File.separator + "temp" + File.separator)) //TE: audio handler.
{//TE: currently launches odDocumentDOC/odSpreadSheetXLS/odMusicMID/odSoundWAV/odMovieAVI files with .doc extension...
if (!System.getProperty("os.name").equalsIgnoreCase("SunOS")) //TE: Check if the operating system is Sun if so don't attempt to launch the document.
{
String path = CBCache.getDirPath();
String filePath = desc.substring(desc.indexOf("temp", desc.lastIndexOf("\"")));
String fileName = filePath.substring(filePath.indexOf("\\"));
String extension = fileName.substring(fileName.indexOf("."));
CBLauncher.launchProgram(extension, path + fileName);
}
}
else if (!System.getProperty("os.name").equalsIgnoreCase("SunOS") && desc.toLowerCase().startsWith("mailto")) //TE: spawn default mail client (windows only).
{//TE: launches email client...
launchClient(desc);
}
else
{
URL url = e.getURL();
// XXX
// Have had no end of trouble trying to do string matching of paths (shame there sin't a decent OO way of doing it with File
// objects!). As a result have switched everything to using 'canonical paths'... hopefully that will work :-). - CB
// XXX
//CB - base no longer used? if (base != null && url.getProtocol().equals("file")) // possibly this is another template...
if (url.getProtocol().equals("file")) // possibly this is another template...
{
String fullFileName = "";
String baseTemplateDirPath = "";
String pluginTemplateDirectoryPath = "";
try
{
// Assume this is a template, and attempt to obtain template name from url...
fullFileName = new File(URLDecoder.decode(url.getFile(), "UTF-8")).getCanonicalPath(); // wierd processing to get standard file separators ('/' or '\') (needed for matching below)
baseTemplateDirPath = baseTemplateDir.getCanonicalPath();
if (pluginTemplateDirectory != null)
pluginTemplateDirectoryPath = pluginTemplateDirectory.getCanonicalPath();
}
catch (IOException e) // not expected...
{
log.log(Level.WARNING, "Exception trying to access HTML file urls " + url.getFile().toString(), e);
}
String fileName = "";
if (fullFileName.startsWith(baseTemplateDirPath))
{
fileName = fullFileName.substring(baseTemplateDirPath.length());
}
//TODO: this needs to be tested -> do urls between plugin templates work...
else if (pluginTemplateDirectory!=null && fullFileName.startsWith(pluginTemplateDirectoryPath))
{
fileName = fullFileName.substring(pluginTemplateDirectoryPath.length());
}
if (fileName.startsWith(File.separator))
fileName = fileName.substring(1);
fileName = (new File(fileName)).toString();
if (templateExists(fileName))
{
setNewTemplate(fileName);
}
else
{
openPage(url);
}
}
else
{ //TE: if the user has set (via advanced options) to launch URLs in a browser...
if ((JXplorer.getProperty("option.url.handling")).equalsIgnoreCase("Launch"))
launchClient(desc);
//TE: otherwise open it in JXplorer...
else
openPage(url);
}
}
}
});
}
}
};
/**
* Recreates the editor, and sets the text.
* @param htmlText the Text (possibly html) to display
*/
public void setEditorText(String htmlText)
{
//System.out.println("-----------\n" + htmlText + "\n----------------\n");
Dimension current = null;
if (editor != null) // reuse editor to avoid memory leak.
// TODO: figure out what the JEditorPane doco means about recreating the document
{
try
{
editor.setText(htmlText);
}
catch (Exception e) // can Sun write code? No, no I don't think they can. If the editor screws up internally, make it again.
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -