//------------------------------------------------------------------------------ // Copyright (c) 2005, 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 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.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.edit.provider.ItemProviderAdapter; import org.eclipse.epf.common.serviceability.Logger; import org.eclipse.epf.common.utils.FileUtil; import org.eclipse.epf.common.utils.NetUtil; import org.eclipse.epf.library.configuration.ConfigurationHelper; import org.eclipse.epf.library.edit.configuration.PracticeSubgroupItemProvider; import org.eclipse.epf.library.edit.util.MethodElementPropUtil; import org.eclipse.epf.library.edit.util.PracticePropUtil; import org.eclipse.epf.library.edit.util.TngUtil; import org.eclipse.epf.library.layout.Bookmark; 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.util.IconUtil; import org.eclipse.epf.publishing.PublishingPlugin; import org.eclipse.epf.publishing.PublishingResources; import org.eclipse.epf.uma.ContentCategory; import org.eclipse.epf.uma.CustomCategory; import org.eclipse.epf.uma.DescribableElement; import org.eclipse.epf.uma.MethodConfiguration; import org.eclipse.epf.uma.MethodElement; import org.eclipse.epf.uma.Practice; import org.eclipse.epf.uma.VariabilityElement; import org.eclipse.epf.uma.ecore.util.OppositeFeature; import org.eclipse.epf.uma.util.UserDefinedTypeMeta; import org.eclipse.osgi.util.NLS; /** * The abstract base class for all publishing view builders. * * @author Jinhua Xi * @author Kelvin Low * @author Weiping Lu * @since 1.0 */ public abstract class AbstractViewBuilder { protected static final int TIMEOUT_INTERVAL = 600000; // in milliseconds protected static boolean profiling = PublishingPlugin.getDefault() .isProfiling(); protected ISiteGenerator siteGenerator; protected PublishOptions options; protected MethodConfiguration config; protected Bookmark defaultView; PublishingRunnable runnable = null; /** * Creates a new instance. * * @param generator * a site generator */ public AbstractViewBuilder(ISiteGenerator generator) { this.siteGenerator = generator; this.options = generator.getPublishOptions(); this.config = generator.getHtmlBuilder().getLayoutManager() .getConfiguration(); this.runnable = new PublishingRunnable(generator.getHtmlBuilder(), TIMEOUT_INTERVAL); } /** * Gets the site generator. * * @return the site generator assigned to this view builder */ public ISiteGenerator getSiteGenerator() { return this.siteGenerator; } /** * Gets the HTML builder. * * @return the HTML builder assigned to this view builder */ public HtmlBuilder getHtmlBuilder() { return this.siteGenerator.getHtmlBuilder(); } /** * Gets the publishing options. * * @return the publishing options assigned to this view builder */ public PublishOptions getOptions() { return this.siteGenerator.getPublishOptions(); } /** * Gets the layout manager. * * @return an element layout manager assigned to this view builder */ public ElementLayoutManager getLayoutMgr() { return getHtmlBuilder().getLayoutManager(); } /** * Gets the content validator. * * @return an element layout manager assigned to this view builder */ public PublishingContentValidator getValidator() { return (PublishingContentValidator) getHtmlBuilder().getValidator(); } /** * Checks whether a method element can be published or not. * * @param element * a method element * @return <code>true</code> if the method element can be published */ protected boolean canPublish(MethodElement element) { return isVisible(element); } /** * Checks whether a method element will be visible in the published web * site. * * @param element * a method element * @return <code>true</code> if the method element will be visible in the * published web site */ protected boolean isVisible(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(); } /** * Publishes the element, collects the linked elements in the published * content. * * @param monitor * a progress monitor * @param element * a method element */ protected void publish(final IProgressMonitor monitor, final MethodElement element) { // System.out.println("--- Begin publishing element " + // element.getGuid() + ":" + element.getType().getName() + ":" + // element.getName() ); try { List linkedElements = getValidator() .getReferencedElements(); List publishedElements = getValidator() .getPublishedElements(); HtmlBuilder htmlBuilder = getHtmlBuilder(); if (!canPublish(element)) { htmlBuilder.getValidator().logWarning(element, PublishingResources.invalidElementWarning_msg); } else if (!publishedElements.contains(element)) { try { if (monitor != null) { String str; if (linkedElements != null) { str = NLS .bind( PublishingResources.publishingLinkedElementTask_name, Integer .toString(publishedElements .size()), Integer .toString(linkedElements .size())); } else { str = NLS .bind( PublishingResources.publishingElementTask_name, element.getType().getName(), element.getName()); } monitor.subTask(str); } IElementLayout layout = htmlBuilder .getLayoutManager() .getLayout(element, true); // String htmlfile = htmlBuilder.generateHtml(layout); String htmlfile = runnable.generateHtml(layout); elementPublished(layout, htmlfile); } catch (Exception ex) { htmlBuilder .getValidator() .logError( element, NLS .bind( PublishingResources.publishElementError_msg, ex.getMessage()), ex); } publishedElements.add(element); } else { // System.out.println("Already generated: " + // getURL(element) ); } } catch (RuntimeException e) { getHtmlBuilder() .getValidator() .logError( element, NLS .bind( PublishingResources.publishElementError_msg, e.getMessage()), e); } } protected void elementPublished(IElementLayout layout, String htmlfile) { } private void copyNodeIcon(File source) { String name = source.getName(); File dest = new File(siteGenerator.getNodeIconPath(), name); if (FileUtil.copyFile(source, dest) == false) { getHtmlBuilder().getValidator().logWarning( NLS.bind(PublishingResources.copyFileWarning_msg, source .getAbsolutePath(), dest.getAbsolutePath())); } } protected String getNodeIconName(Object obj) { File iconFile = null; String iconName = null; if (obj instanceof DescribableElement) { URI uri = ((DescribableElement) obj).getNodeicon(); VariabilityElement uriInheritingBase = null; if (uri == null && config != null && obj instanceof VariabilityElement) { VariabilityElement[] uriInheritingBases = new VariabilityElement[1]; uri = ConfigurationHelper.getInheritingUri((DescribableElement) obj, uri, uriInheritingBases, config, 0); uriInheritingBase = uriInheritingBases[0]; } 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())); // To handle the nodeIcon uri, EPF 1.2, its changed now it // is relative to plugin path. iconFile = new File( TngUtil.getFullPathofNodeorShapeIconURI( uriInheritingBase == null ? (EObject) obj : uriInheritingBase, uri)); } } } 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(); if (obj instanceof CustomCategory) { CustomCategory cc = (CustomCategory) obj; MethodElementPropUtil propUtil = MethodElementPropUtil .getMethodElementPropUtil(); if (propUtil.isTransientElement(cc)) { if (cc.getName().equals("Roles")) {//$NON-NLS-1$ type = "roleset";//$NON-NLS-1$ } else if (cc.getName().equals("Tasks")) {//$NON-NLS-1$ type = "discipline";//$NON-NLS-1$ } else if (cc.getName().equals("Work Products")) {//$NON-NLS-1$ type = "domain";//$NON-NLS-1$ } else if (cc.getName().equals("Guidance")) {//$NON-NLS-1$ type = "guidances";//$NON-NLS-1$ } else if (cc.getName().equals("Processes")) {//$NON-NLS-1$ type = "processes";//$NON-NLS-1$ } } } if ((obj instanceof Practice) && (PracticePropUtil.getPracticePropUtil().isUdtType((Practice)obj))) { type = "UDT"; //$NON-NLS-1$ //for user defined type try { boolean debug = PublishingPlugin.getDefault().isDebugging(); Logger logger = PublishingPlugin.getDefault().getLogger(); UserDefinedTypeMeta udtMeta = PracticePropUtil.getPracticePropUtil().getUtdData((Practice)obj); String icon = udtMeta.getRteNameMap().get(UserDefinedTypeMeta._icon); if (debug) { logger.logInfo("The udt node icon get from meta: " + icon); //$NON-NLS-1$ } if (icon != null) { iconFile = new File(NetUtil.decodedFileUrl(new URL(icon).getFile())); if (debug) { logger.logInfo("The udt node icon file: " + iconFile); //$NON-NLS-1$ } } } catch (Exception e) { getHtmlBuilder().getValidator().logError("", e); //$NON-NLS-1$ iconFile = null; } } if (iconFile == null) { iconFile = IconUtil.getNodeIconFile(type); } } else if (obj instanceof PracticeSubgroupItemProvider) { iconFile = IconUtil.getNodeIconFile((PracticeSubgroupItemProvider) obj); } } 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; } /** * Gets the display name for a method element or iterm provider adapter. * * @param obj * a method element or iterm provider adapter * @return the display name or <code>null</code> */ 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; } /** * Gets the GUID for a method element. * * @param obj * a method element * @return the GUID for a method element or <code>null</code> */ private String getGUID(Object obj) { if (obj instanceof MethodElement) { return ((MethodElement) obj).getGuid(); } else return null; } /** * Gets thr URL for a method element. * * @param obj * a method element * @return the URL for a method element or a blank HTML */ private String getURL(Object obj) { if (obj instanceof MethodElement) { return getLayoutMgr().getLayout((MethodElement) obj, true).getUrl(); } else { // FIXME: layout needs to be provided for uncategorized and category // object return "applet//empty.htm"; //$NON-NLS-1$ } } /** * Creates a bookmark for a method element * * @param element * a method element * @return a <code>Bookmark</code> */ 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); } // 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; } /** * Gets the default view. * * @return a <code>Bookmark</code> that encapsulates the default view */ public Bookmark getDefaultView() { return defaultView; } /** * Builds the views and returns a list of bookmark objects. * * @param monitor * a progress monitor * @return a list of <code>Bookmark</code> */ public abstract List<Bookmark> buildViews(IProgressMonitor monitor); /** * Disposes this object. */ public void dispose() { config = null; if ( runnable != null ) { runnable.dispose(); runnable = null; } if ( siteGenerator != null ) { siteGenerator.dispose(); siteGenerator = null; } } }