| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 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 implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.publishing.services; |
| |
| import java.io.File; |
| import java.net.URI; |
| import java.net.URL; |
| import java.net.URLDecoder; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.edit.provider.ItemProviderAdapter; |
| import org.eclipse.epf.common.utils.Timer; |
| import org.eclipse.epf.library.LibraryService; |
| import org.eclipse.epf.library.configuration.ConfigurationHelper; |
| import org.eclipse.epf.library.layout.ElementLayoutManager; |
| import org.eclipse.epf.library.layout.HtmlBuilder; |
| import org.eclipse.epf.library.layout.IElementLayout; |
| import org.eclipse.epf.library.layout.LayoutResources; |
| import org.eclipse.epf.library.util.IconUtil; |
| import org.eclipse.epf.library.util.ResourceHelper; |
| import org.eclipse.epf.publishing.PublishingResources; |
| import org.eclipse.epf.publishing.layout.Bookmark; |
| import org.eclipse.epf.uma.ContentCategory; |
| import org.eclipse.epf.uma.DescribableElement; |
| import org.eclipse.epf.uma.MethodConfiguration; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.ecore.util.OppositeFeature; |
| import org.eclipse.osgi.util.NLS; |
| |
| import sun.security.action.GetBooleanAction; |
| |
| |
| /** |
| * abstract class for publishing views |
| * |
| * @author Jinhua Xi |
| * @since 1.0 |
| */ |
| public abstract class AbstractViewBuilder { |
| |
| // private static final String APPLET_PATH = "applet" + File.separatorChar; //$NON-NLS-1$ |
| // private static final String NO_APPLET_PATH = "noapplet" + File.separatorChar; //$NON-NLS-1$ |
| // private static final String ICON_PATH = "images" + File.separatorChar; //$NON-NLS-1$ |
| //private static final String ICON_ZIP_FILE = "rpw_img.zip"; //$NON-NLS-1$ |
| |
| |
| // instead of publishing the whole content library, we collect the elements show up in the view tree |
| // only publish those element show up in the view and it's referenced (including content reference) elements |
| //protected List elementsTobePublished = new ArrayList(); |
| |
| // move this to validator as well |
| //protected List publishedElements = new ArrayList(); |
| |
| //protected HtmlBuilder builder; |
| protected ISiteGenerator siteGenerator; |
| |
| protected MethodConfiguration config; |
| |
| protected Bookmark defaultView = null; |
| |
| protected PublishOptions options = null; |
| |
| // protected File iconPath; |
| |
| protected static final int timeout_millis = 600000; // 10 minutes??? |
| |
| /** |
| * construct an AbstractViewBuilder object |
| * |
| * @param builder HtmlBuilder |
| * @param options PublishOptions |
| */ |
| public AbstractViewBuilder(ISiteGenerator generator) |
| { |
| this.siteGenerator = generator; |
| this.options = this.siteGenerator.getPublishOptions(); |
| |
| this.config = this.siteGenerator.getHtmlBuilder().getLayoutManager().getConfiguration(); |
| } |
| |
| public ISiteGenerator getSiteGenerator() { |
| return this.siteGenerator; |
| } |
| |
| /** |
| * get the HtmlBuilder |
| * @return HtmlBuilder |
| */ |
| public HtmlBuilder getHtmlBuilder() |
| { |
| return this.siteGenerator.getHtmlBuilder(); |
| } |
| |
| /** |
| * get the PublishOptions |
| * @return PublishOptions |
| */ |
| public PublishOptions getOptions() |
| { |
| return this.siteGenerator.getPublishOptions(); |
| } |
| |
| /** |
| * get the ElementLayoutManager |
| * @return ElementLayoutManager |
| */ |
| public ElementLayoutManager getLayoutMgr() |
| { |
| return getHtmlBuilder().getLayoutManager(); |
| } |
| |
| /** |
| * get the content validator. |
| * @return PublishingContentValidator |
| */ |
| public PublishingContentValidator getValidator() |
| { |
| return (PublishingContentValidator)getHtmlBuilder().getValidator(); |
| } |
| |
| /** |
| * check if the element is publishable or not. |
| * |
| * @param element MethodElement |
| * @return boolean |
| */ |
| protected boolean canPublish(MethodElement element) |
| { |
| return canShow(element); |
| } |
| |
| protected boolean canShow(MethodElement element) { |
| if (element == null) { |
| return false; |
| } |
| |
| if ( getValidator().isDiscarded(null, null, element) ) |
| { |
| return false; |
| } |
| |
| if ( !ConfigurationHelper.canShow(element, config) ) { |
| return false; |
| } |
| |
| if ( options.isPublishProcess()) { |
| return getValidator().inClosure(element); |
| } else { |
| return true; |
| } |
| } |
| |
| protected void discardEmptyCategory(ContentCategory element, boolean discard) |
| { |
| if ( discard ) |
| { |
| getValidator().setDiscardedElement(element); |
| getValidator().logWarning(element, PublishingResources.discaredCategoryWarning_msg); |
| } |
| else |
| { |
| getValidator().addValidCategory( (ContentCategory)element); |
| } |
| } |
| |
| protected MethodElement calc01FeatureValue(MethodElement element, EStructuralFeature feature) { |
| return ConfigurationHelper.calc01FeatureValue(element, feature, getLayoutMgr().getElementRealizer()); |
| } |
| |
| protected List calc0nFeatureValue(MethodElement element, EStructuralFeature feature) { |
| return ConfigurationHelper.calc0nFeatureValue(element, feature, getLayoutMgr().getElementRealizer()); |
| } |
| |
| protected MethodElement calc01FeatureValue(MethodElement element, OppositeFeature feature) { |
| return ConfigurationHelper.calc01FeatureValue(element, feature, getLayoutMgr().getElementRealizer()); |
| } |
| |
| protected List calc0nFeatureValue(MethodElement element, OppositeFeature feature) { |
| return ConfigurationHelper.calc0nFeatureValue(element, feature, getLayoutMgr().getElementRealizer()); |
| } |
| |
| protected List getPublishedElements() { |
| return getValidator().getPublishedElements(); |
| } |
| |
| /** |
| * publish the element, collect the linked elements in the published contents |
| * @param monitor |
| * @param element |
| * @param recursive |
| * @param linkedElements |
| */ |
| protected void publish(final IProgressMonitor monitor, final MethodElement element) |
| { |
| //System.out.println("--- Begin publishing element " + element.getGuid() + ":" + element.getType().getName() + ":" + element.getName() ); |
| Runnable runnable = new Runnable(){ |
| public void run() { |
| |
| try { |
| List linkedElements = getValidator().getReferencedElements(); |
| if ( !canPublish(element) ) |
| { |
| getHtmlBuilder().getValidator().logWarning(element, PublishingResources.invalidElementWarning_msg); |
| } |
| else if ( !getPublishedElements().contains(element) ) |
| { |
| try |
| { |
| if ( monitor != null ) |
| { |
| String str; //$NON-NLS-1$ |
| if ( linkedElements != null ) |
| { |
| str = NLS.bind(PublishingResources.publishingLinkedElementTask_name, Integer.toString(getPublishedElements().size()), Integer.toString(linkedElements.size())); |
| } |
| else |
| { |
| str = NLS.bind(PublishingResources.publishingElementTask_name, element.getType().getName(), element.getName()); |
| } |
| monitor.subTask(str); |
| |
| } |
| //builder.generateHtml(element); |
| IElementLayout layout = getHtmlBuilder().getLayoutManager().getLayout(element, true); |
| String htmlfile = getHtmlBuilder().generateHtml(layout); |
| |
| elementPublished(layout, htmlfile); |
| |
| } |
| catch (Exception ex) |
| { |
| //ex.printStackTrace(); |
| getHtmlBuilder().getValidator().logError(element, NLS.bind(PublishingResources.publishElementError_msg, ex.getMessage()), ex); |
| } |
| getPublishedElements().add(element); |
| } |
| else |
| { |
| //System.out.println("Already generated: " + getURL(element) ); |
| } |
| |
| // if ( recursive ) |
| // { |
| // // iterator all contained and referenced elements |
| // EList children = element.eContents(); |
| // if ( children != null && children.size()>0 ) |
| // { |
| // for (Iterator it = children.iterator(); it.hasNext(); ) |
| // { |
| // Object e = it.next(); |
| // if ( e instanceof ContentDescription) |
| // { |
| // continue; |
| // } |
| // |
| // if ( e instanceof MethodElement ) |
| // { |
| // publish(monitor, (MethodElement)e, true); |
| // } |
| // else |
| // { |
| // //System.out.println("Not method element,can't publish: " + e); |
| // builder.getValidator().logWarning(element, PublishingResources.formatString("Publishing.invalidMethodElementWarning.msg", e.toString())); //$NON-NLS-1$ |
| // } |
| // } |
| // } |
| // } |
| } catch (RuntimeException e) { |
| //e.printStackTrace(); |
| getHtmlBuilder().getValidator().logError(element, NLS.bind(PublishingResources.publishElementError_msg, e.getMessage()), e); |
| } |
| //System.out.println("--- End publishing element " + element.getGuid() + ":" + element.getType().getName() + ":" + element.getName() ); |
| |
| }}; |
| |
| |
| Timer timer = new Timer(); |
| try { |
| // set the target element for thre content validator |
| getValidator().setTargetElement(element); |
| |
| // run the publishing and check the time, if timeout, terminate it |
| Thread t = new Thread(runnable); |
| t.start(); |
| t.join(timeout_millis); |
| if ( t.isAlive() ) { |
| // wait for the thread to die and log an error |
| timer.stop(); |
| getValidator().logInfo(element, "publishing element takes " + timer.getTime() + " mini seconds already and is still not done yet ..."); //$NON-NLS-1$ //$NON-NLS-2$ |
| timer.start(); |
| t.join(); |
| } |
| } catch (InterruptedException e1) { |
| e1.printStackTrace(); |
| } |
| finally { |
| getValidator().setTargetElement(null); |
| getValidator().getReferencedElements().remove(element); |
| |
| timer.stop(); |
| getValidator().logInfo(element, timer.getTotalTime() + " mini seconds publishing element" ); //$NON-NLS-1$ |
| } |
| |
| } |
| |
| protected void elementPublished(IElementLayout layout, String htmlfile) { |
| |
| } |
| |
| private void copyNodeIcon(File source) |
| { |
| String name = source.getName(); |
| |
| File dest = new File(siteGenerator.getNodeIconPath(), name); |
| if ( ResourceHelper.copyFile(source, dest) == false ) |
| { |
| getHtmlBuilder().getValidator().logWarning(NLS.bind(PublishingResources.copyFileWarning_msg, source.getAbsolutePath(), dest.getAbsolutePath())); |
| } |
| |
| } |
| |
| private String getNodeIconName(Object obj) |
| { |
| File iconFile = null; |
| String iconName = null; |
| |
| if ( obj instanceof DescribableElement ) |
| { |
| URI uri = ((DescribableElement)obj).getNodeicon(); |
| |
| String elementName = ((DescribableElement)obj).getType().getName().toLowerCase(); |
| if (DefaultElementTypeResources.useDefaultIcon(elementName)) |
| uri = null; |
| |
| if ( uri != null ) |
| { |
| // try if this is a valid URL or not |
| boolean isFullPath = false; |
| try |
| { |
| URL url = uri.toURL(); |
| if ( url != null ) |
| { |
| iconFile = new File(URLDecoder.decode(url.getFile(), "UTF-8")); //$NON-NLS-1$ |
| isFullPath = true; |
| } |
| } |
| catch (Exception ex) |
| { |
| ; // not a valid url, maybe a relative path |
| } |
| |
| if ( !isFullPath ) |
| { |
| iconFile = new File(LibraryService.getInstance().getCurrentMethodLibraryPath(), URLDecoder.decode(uri.toString())); |
| } |
| } |
| } |
| |
| if ( (iconFile != null ) && !iconFile.exists() ) |
| { |
| iconFile = null; |
| } |
| |
| if ( iconFile == null ) |
| { |
| // get the default icon name |
| if ( obj instanceof MethodElement ) |
| { |
| String type = ((MethodElement)obj).getType().getName().toLowerCase(); |
| iconFile = IconUtil.getNodeIconFile(type); |
| } |
| } |
| |
| if ( iconFile != null ) |
| { |
| // need to copy the file together and zip for the applet |
| if ( !iconFile.exists() ) |
| { |
| if ( obj instanceof MethodElement ) |
| { |
| getHtmlBuilder().getValidator().logWarning((MethodElement)obj, NLS.bind(PublishingResources.missingIconFileWarning_msg, iconFile.getAbsolutePath())); |
| } |
| else |
| { |
| getHtmlBuilder().getValidator().logWarning(NLS.bind(PublishingResources.missingIconFileWarning_msg, iconFile.getAbsolutePath())); |
| } |
| } |
| |
| copyNodeIcon(iconFile); |
| iconName = iconFile.getName(); |
| } |
| |
| if ( iconName == null || iconName.length() == 0 ) |
| { |
| String name; |
| if ( obj instanceof MethodElement ) |
| { |
| name = ((MethodElement)obj).getName(); |
| } |
| else |
| { |
| name = obj.toString(); |
| } |
| |
| getHtmlBuilder().getValidator().logWarning(NLS.bind(PublishingResources.missingIconNameWarning_msg, name)); |
| } |
| |
| return iconName; |
| } |
| |
| private String getOpenIconName(Object obj) |
| { |
| return ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Get name |
| * @param obj |
| * @return |
| */ |
| private String getName(Object obj) |
| { |
| String name = null; |
| if (obj instanceof MethodElement) |
| { |
| MethodElement e = (MethodElement)obj; |
| |
| // calculate the presentation name, for extenders, get from base if needed |
| name = ConfigurationHelper.getPresentationName(e, config); |
| if ( name == null || name.equals("") ) //$NON-NLS-1$ |
| { |
| name = e.getClass().getName(); |
| int index = name.lastIndexOf("."); //$NON-NLS-1$ |
| if ( index >=0 ) |
| { |
| name = name.substring(index+1); |
| if ( name.endsWith("Impl") ) //$NON-NLS-1$ |
| { |
| name = name.substring(0, name.length()-4); |
| } |
| } |
| } |
| } |
| else if (obj instanceof ItemProviderAdapter) |
| { |
| ItemProviderAdapter provider = (ItemProviderAdapter) obj; |
| name = provider.getText(obj); |
| |
| } |
| return name; |
| } |
| |
| /** |
| * get guid |
| * @param obj |
| * @return |
| */ |
| private String getGUID(Object obj) |
| { |
| if (obj instanceof MethodElement) |
| { |
| return ((MethodElement) obj).getGuid(); |
| } |
| else |
| return null; |
| } |
| |
| /** |
| * get url |
| * @param obj |
| * @return |
| */ |
| private String getURL(Object obj) |
| { |
| if (obj instanceof MethodElement) |
| { |
| return getLayoutMgr().getLayout((MethodElement) obj, true).getUrl(); |
| } |
| else |
| { |
| // TODO - layout needs to be provided for uncategorized and category object |
| return "applet//empty.htm"; //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Create bookmark |
| * @param element |
| * @return Bookmark |
| */ |
| protected Bookmark createBookmark(IProgressMonitor monitor, Object element) |
| { |
| // publish this element, |
| if ( element instanceof MethodElement ) |
| { |
| // delay the publishing till the bookmarks are created. |
| getHtmlBuilder().getValidator().addReferencedElement(null, (MethodElement)element); |
| |
| //this.publish(monitor, (MethodElement)element, false, elementsTobePublished); |
| } |
| |
| // create a bookmark for this element |
| String name = getName(element); |
| String guid = getGUID(element); |
| String url = getURL(element); |
| String nodeIcon = getNodeIconName(element); |
| |
| String msg = NLS.bind(PublishingResources.generatingBookmarkTask_name, name); |
| monitor.subTask(msg); |
| return createBookmark(name, guid, url, nodeIcon, nodeIcon, element); |
| } |
| |
| protected Bookmark createBookmark(String name, String guid, String url, String closeIcon, String openIcon, Object owner) |
| { |
| |
| Bookmark b = new Bookmark(name); |
| b.setPresentationName(name); |
| b.setUniqueId(guid); |
| b.setClosedIconName(closeIcon); |
| b.setOpenIconName(openIcon); |
| b.setFileName(url); |
| b.setFromContentLibrary(true); |
| b.setEnabled(true); |
| b.setExist(true); |
| b.setVisible(true); |
| b.setTransparency(false); |
| b.setDefault(true); |
| b.setCurrent(false); |
| b.setOwner(owner); |
| return b; |
| } |
| |
| /** |
| * get the default view |
| * @return Bookmark |
| */ |
| public Bookmark getDefaultView() |
| { |
| return defaultView; |
| } |
| |
| |
| // protected void copyIconsForNonApplet() |
| // { |
| // try |
| // { |
| // // don't jar it. copy the icons to the images |
| //// File jarFile = new File(builder.getPublishDir(), APPLET_PATH + ICON_ZIP_FILE); |
| //// PublishingUtil.jarFiles(iconPath, jarFile); |
| // |
| // if ( options.useDefaultTreeBrowser ) |
| // { |
| // // also copy the icons to the no-applet folder |
| // LayoutResources.copyDir(iconPath.getAbsolutePath(), builder.getPublishDir() + NO_APPLET_PATH + ICON_PATH); |
| // } |
| // } |
| // catch (Exception ex) |
| // { |
| // ex.printStackTrace(); |
| // } |
| // } |
| |
| /** |
| * build the views and returns a list of Boolmark objects |
| * @param monitor IProgressMonitor |
| * @return List a list of Bookmarks |
| */ |
| public abstract List buildViews(IProgressMonitor monitor); |
| |
| |
| /** |
| * dispose the object. |
| * |
| */ |
| public void dispose() |
| { |
| //publishedElements.clear(); |
| HtmlBuilder builder = getHtmlBuilder(); |
| |
| if ( builder != null ) |
| { |
| builder.getLayoutManager().clear(); |
| builder.dispose(); |
| } |
| config = null; |
| builder = null; |
| } |
| |
| } |