package org.vietspider.ui.htmlexplorer;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.prefs.Preferences;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.TreeItem;
import org.vietspider.common.text.SWProtocol;
import org.vietspider.common.util.Worker;
import org.vietspider.html.HTMLNode;
import org.vietspider.html.Name;
import org.vietspider.html.path2.HTMLExtractor;
import org.vietspider.html.path2.NodePath;
import org.vietspider.html.path2.NodePathParser;
import org.vietspider.html.util.HTMLParserDetector;
import org.vietspider.html.util.HyperLinkUtil;
import org.vietspider.ui.services.ClientLog;
import org.vietspider.ui.widget.waiter.WaitLoading;
public class HTMLExplorer extends HTMLExplorerViewer {
public final static int NONE = 0, SECTION = 1, CONTENT = 2;
private boolean cache = false;
private boolean decode = false;
private String refer;
public HTMLExplorer(Composite parent){
super(parent);
}
public void goAddress(){
String strAddress = toolbar.getText();
if(strAddress.indexOf("//") < 0) strAddress = "http://"+strAddress;
if(strAddress == null || strAddress.trim().length() == 0) strAddress = openFile();
if(strAddress == null || strAddress.trim().length() < 1) return;
try {
File file = new File(strAddress);
if(file.exists()){
URL url = file.toURI().toURL();
strAddress = url.toString();
}
} catch( Exception exp) {
ClientLog.getInstance().setMessage(getShell(), exp);
}
browser.setUrl(strAddress);
Preferences prefs = Preferences.userNodeForPackage(HTMLExplorer.class);
prefs.put("url.address", strAddress);
charset = null;
}
String openFile(){
Preferences prefs = Preferences.userNodeForPackage(getClass());
String path = prefs.get("path", "");
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
if(path != null) dialog.setFilterPath( path);
path = dialog.open();
if( path == null || path.trim().equals("")) return null;
prefs.put("path", path);
charset = null;
return path;
}
public void selectAddress(final String ...paths) {
Worker excutor = new Worker() {
private String url ;
private String html;
public void abort() {
webClient.abort(url);
}
public void before() {
url = browser.getUrl();
if(url == null || url.equals("about:blank") || url.trim().isEmpty()) {
url = toolbar.getText();
}
}
public void execute() {
try {
HTMLParserDetector detector = new HTMLParserDetector();
detector.setDecode(decode);
detector.setCharset(charset);
if(html == null || html.trim().isEmpty()) {
document = webClient.createDocument(refer, url, cache, detector);
} else {
// System.out.println(html);
document = detector.createDocument(html);
}
if(charset == null) charset = detector.getCharset();
removeIFrameSource(document.getRoot());
} catch(Exception exp) {
ClientLog.getInstance().setException(null, exp);
}
}
public void after() {
selectedAddress = url;
toolbar.setText(url);
toolbar.addAddressToList(url);
tree.removeAll();
if(document != null) handler.createTreeItem(tree, document);
new AutoSelectDataNode2(document, url, handler, tree);
if(paths.length < 1) {
HTMLExtractor extractor = new HTMLExtractor();
NodePathParser pathParser = new NodePathParser();
if(hyperlinkUtil == null) hyperlinkUtil = new HyperLinkUtil();
HTMLNode header = null;
HTMLNode body = null;
try {
NodePath nodePath = pathParser.toPath("HEAD");
header = extractor.lookNode(document.getRoot(), nodePath);
nodePath = pathParser.toPath("BODY");
body = extractor.lookNode(document.getRoot(), nodePath);
} catch (Exception e) {
ClientLog.getInstance().setException(getShell(), e);
}
if(header == null || body == null) return;
try {
String address = toolbar.getText();
URL home = new URL(address);
hyperlinkUtil.createFullNormalLink(document.getRoot(), home);
hyperlinkUtil.createFullImageLink(document.getRoot(), home);
Map<String,String> map = new HashMap<String,String>();
map.put("link","href");
map.put("script","src");
hyperlinkUtil.createFullLink(header, map, home, null);
} catch (Exception e) {
ClientLog.getInstance().setException(getShell(), e);
}
searchRenderer.viewDocument(header, body, url);
}
if(document != null) {
short selectType = PathConfirmDialog.YES;
for(String path : paths) {
selectType = setPath(path, TreeHandler.SELECT, selectType);
}
} else {
browser.setUrl(url);
for(String path : paths) lstPath.add(path);
}
}
};
new WaitLoading(toolbar, excutor).open();
}
public short setPath(String path, int style, short selectType){
if(path == null) return PathConfirmDialog.NO;
try {
selectType = handler.traverseTree(tree, path, style, selectType);
if(style == TreeHandler.SELECT
&& (selectType == PathConfirmDialog.NO
|| selectType == PathConfirmDialog.NO_TO_ALL)) {
lstPath.add(path);
}
} catch (Exception e) {
ClientLog.getInstance().setMessage(tree.getShell(), e);
}
selectTree();
return selectType;
}
void selectTree() {
TreeItem[] items = tree.getSelection();
if( items == null || items.length < 1) return;
TreeItem item = items[0];
String txt = handler.getConfig(item);
txtPath.setText(txt);
treeAddButton.computeShowArea(item);
HTMLExtractor extractor = new HTMLExtractor();
NodePathParser pathParser = new NodePathParser();
try {
NodePath nodePath = pathParser.toPath(txt);
HTMLNode node = extractor.lookNode(document.getRoot(), nodePath);
if(node == null) return;
if(node.isNode(Name.CONTENT)
|| node.isNode(Name.COMMENT)
|| node.isNode(Name.UNKNOWN)) {
browser.setText(node.getTextValue());
return;
}
NodePath headerPath = pathParser.toPath("HEAD");
HTMLNode header = extractor.lookNode(document.getRoot(), headerPath);
if(toolbar.isShowAll()) {
if(hyperlinkUtil == null) hyperlinkUtil = new HyperLinkUtil();
try {
String address = toolbar.getText();
URL home = new URL(address);
hyperlinkUtil.createFullNormalLink(node, home);
hyperlinkUtil.createFullImageLink(node, home);
HashMap<String, String> map = new HashMap<String,String>();
map.put("link","href");
map.put("script","src");
hyperlinkUtil.createFullLink(header, map, home, null);
} catch(MalformedURLException me) {
} catch (Exception e) {
ClientLog.getInstance().setException(getShell(), e);
}
}
StringBuilder builder = new StringBuilder();
builder.append("<html>");
builder.append("<head>");
if(toolbar.isShowAll() && header != null && header.getChildren() != null) {
for(HTMLNode ele : header.getChildren()){
builder.append(ele.getTextValue()).append('\n');
}
}
// String baseHref = HTMLExplorer.class.getResource("").toString();
// builder.append("<base href=\""+baseHref+"\">");
if(node.isNode(Name.BODY)) {
HTMLNode body = null;
try {
nodePath = pathParser.toPath("BODY");
body = extractor.lookNode(document.getRoot(), nodePath);
} catch (Exception e) {
ClientLog.getInstance().setException(getShell(), e);
}
if(header == null || body == null) return;
searchRenderer.viewDocument(header, body, null);
} else {
searchRenderer.viewDocument(null, node, null);
// builder.append("</head>");
// builder.append("<body>");
// builder.append(node.getTextValue());
// builder.append("</body></html>");
// browser.setText(builder.toString());
}
} catch(Exception exp){
ClientLog.getInstance().setException(getShell(), exp);
}
}
public String[] addItems(){
TreeItem[] items = tree.getSelection();
if( items == null || items.length < 1) return null;
for(TreeItem item : items) {
lstPath.add(handler.getConfig(item));
}
return lstPath.getItems();
}
String editItem(){
String path = txtPath.getText();
int selectedIndex = lstPath.getSelectionIndex();
if(selectedIndex < 0 || selectedIndex> lstPath.getItemCount()) {
lstPath.add(path);
return path;
}
lstPath.setItem(selectedIndex, path);
return path;
}
void removeItem() throws Exception {
TreeItem[] items = tree.getSelection();
if( items == null || items.length < 1) return;
List<String> list = new ArrayList<String>();
for(TreeItem item : items) {
String path = handler.getConfig(item);
for(int i=0; i<lstPath.getItemCount(); i++){
if(lstPath.getItem(i).equals(path)){
lstPath.remove(i);
break;
}
}
list.add(path);
}
traverseTree(TreeHandler.REMOVE, list.toArray(new String[list.size()]));
txtPath.setText("");
}
void viewItem(){
TreeItem[] items = tree.getSelection();
if( items == null || items.length < 1) return;
int x = getShell().getLocation().x+120, y = getShell().getLocation().y +130;
HTMLExtractor extractor = new HTMLExtractor();
NodePathParser pathParser = new NodePathParser();
for(TreeItem item : items) {
String pathIndex = handler.getConfig(item);
try {
NodeInfoViewer viewer = new NodeInfoViewer(getShell(), x, y);
NodePath nodePath = pathParser.toPath(pathIndex);
HTMLNode node = extractor.lookNode(document.getRoot(), nodePath);
viewer.setNode(node);
x += 10;
y += 10;
nodeViewers.add(viewer);
} catch(Exception exp) {
ClientLog.getInstance().setMessage(getShell(), exp);
}
}
}
public List<String> traverseTree(int style, String[] paths) throws Exception {
// String [] paths = cboPath.getItems();
List<String> removePaths = new ArrayList<String>();
NodePathParser pathParser = new NodePathParser();
if(paths != null) {
short selectType = PathConfirmDialog.YES;
for(String path : paths) {
NodePath nodePath = pathParser.toPath(path);
selectType = handler.traverseTree(tree, nodePath, path, style, selectType);
if(selectType == PathConfirmDialog.YES
|| selectType == PathConfirmDialog.YES_TO_ALL) {
removePaths.add(path);
}
}
}
return removePaths;
}
public void search(String value){
createDocument();
super.search(value);
}
private void createDocument(){
if(document == null){
selectAddress();
return;
}
String browserURL = browser.getUrl();
if(browserURL == null || browserURL.trim().length() == 0) return;
if(!SWProtocol.isHttp(browserURL)) return;
if(browserURL.equals(selectedAddress)) return;
selectAddress();
}
public void reset() {
browser.setText("<html></html>");
lstPath.removeAll();
tree.removeAll();
txtPath.setText("");
charset = null;
selectedAddress = null;
document = null;
decode = false;
}
public void setWebClient(FastWebClient webClient) { this.webClient = webClient; }
public void setRefer(String refer) { this.refer = refer; }
public void setCache(boolean cache) { this.cache = cache; }
public void setDecode(boolean decode) { this.decode = decode; }
}