| /* |
| * Copyright (c) 2011, 2012, 2015 Eike Stepper (Berlin, Germany) 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: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo.releng.doc.article.impl; |
| |
| import org.eclipse.emf.cdo.releng.doc.AssembleScripts; |
| import org.eclipse.emf.cdo.releng.doc.article.ArticlePackage; |
| import org.eclipse.emf.cdo.releng.doc.article.Category; |
| import org.eclipse.emf.cdo.releng.doc.article.Chapter; |
| import org.eclipse.emf.cdo.releng.doc.article.Context; |
| import org.eclipse.emf.cdo.releng.doc.article.Documentation; |
| import org.eclipse.emf.cdo.releng.doc.article.EmbeddableElement; |
| import org.eclipse.emf.cdo.releng.doc.article.Javadoc; |
| import org.eclipse.emf.cdo.releng.doc.article.Plugin; |
| import org.eclipse.emf.cdo.releng.doc.article.Schemadoc; |
| import org.eclipse.emf.cdo.releng.doc.article.StructuralElement; |
| import org.eclipse.emf.cdo.releng.doc.article.util.ArticleUtil; |
| |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.NotificationChain; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.InternalEObject; |
| import org.eclipse.emf.ecore.impl.ENotificationImpl; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.util.EObjectContainmentEList; |
| import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList; |
| import org.eclipse.emf.ecore.util.EObjectEList; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.ecore.util.InternalEList; |
| |
| import com.sun.javadoc.ClassDoc; |
| import com.sun.javadoc.MethodDoc; |
| import com.sun.javadoc.PackageDoc; |
| import com.sun.javadoc.RootDoc; |
| import com.sun.javadoc.Tag; |
| |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| |
| /** |
| * <!-- begin-user-doc --> An implementation of the model object '<em><b>Documentation</b></em>'. <!-- end-user-doc --> |
| * <p> |
| * The following features are implemented: |
| * <ul> |
| * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getContext <em>Context</em>}</li> |
| * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getEmbeddableElements <em>Embeddable |
| * Elements</em>}</li> |
| * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getDependencies <em>Dependencies</em>}</li> |
| * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getProject <em>Project</em>}</li> |
| * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getPlugins <em>Plugins</em>}</li> |
| * </ul> |
| * </p> |
| * |
| * @generated |
| */ |
| public class DocumentationImpl extends StructuralElementImpl implements Documentation |
| { |
| private static final String HTML = "html"; |
| |
| private static final String PLUGINS = "plugins"; |
| |
| private static final String JAVADOC_MARKER_CLASS = "Javadoc"; |
| |
| private static final String SCHEMADOC_MARKER_CLASS = "Schemadoc"; |
| |
| private static final boolean LOCAL = false; |
| |
| /** |
| * The cached value of the '{@link #getEmbeddableElements() <em>Embeddable Elements</em>}' containment reference list. |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @see #getEmbeddableElements() |
| * @generated |
| * @ordered |
| */ |
| protected EList<EmbeddableElement> embeddableElements; |
| |
| /** |
| * The cached value of the '{@link #getDependencies() <em>Dependencies</em>}' reference list. <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * |
| * @see #getDependencies() |
| * @generated |
| * @ordered |
| */ |
| protected EList<Documentation> dependencies; |
| |
| /** |
| * The default value of the '{@link #getProject() <em>Project</em>}' attribute. <!-- begin-user-doc --> <!-- |
| * end-user-doc --> |
| * |
| * @see #getProject() |
| * @generated |
| * @ordered |
| */ |
| protected static final String PROJECT_EDEFAULT = null; |
| |
| /** |
| * The cached value of the '{@link #getProject() <em>Project</em>}' attribute. <!-- begin-user-doc --> <!-- |
| * end-user-doc --> |
| * |
| * @see #getProject() |
| * @generated |
| * @ordered |
| */ |
| protected String project = PROJECT_EDEFAULT; |
| |
| /** |
| * The cached value of the '{@link #getPlugins() <em>Plugins</em>}' containment reference list. <!-- begin-user-doc |
| * --> <!-- end-user-doc --> |
| * |
| * @see #getPlugins() |
| * @generated |
| * @ordered |
| */ |
| protected EList<Plugin> plugins; |
| |
| private StructuralElement defaultElement; |
| |
| private final List<StructuralElement> navElements = new ArrayList<StructuralElement>(); |
| |
| private boolean analyzed; |
| |
| private File projectFolder; |
| |
| private String basePathForChildren; |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| protected DocumentationImpl() |
| { |
| super(); |
| } |
| |
| DocumentationImpl(Context context, String project) |
| { |
| super(null, null, context.getRoot()); |
| setContext(context); |
| this.project = project; |
| context.register(getId(), this); |
| |
| basePathForChildren = PLUGINS + "/" + project + "/" + HTML; |
| projectFolder = new File(new File(getContext().getBaseFolder(), PLUGINS), project); |
| |
| setTitle(AssembleScripts.getPluginName(projectFolder)); |
| |
| analyzeDependencies(projectFolder); |
| loadPlugins(projectFolder); |
| analyzeDocumentation(projectFolder); |
| if (defaultElement == null) |
| { |
| throw new AssertionError("No default element declared in " + getTitle()); |
| } |
| |
| setPath(defaultElement.getFullPath()); |
| analyzed = true; |
| collectNavElements(navElements); |
| } |
| |
| public void registerElement(StructuralElement element) |
| { |
| if (element != this) |
| { |
| getContext().register(element.getId(), element); |
| } |
| } |
| |
| private void analyzeDependencies(File projectFolder) |
| { |
| Context context = getContext(); |
| for (String dependency : AssembleScripts.getDependencies(projectFolder)) |
| { |
| if (context.getDocumentation(dependency) == null) |
| { |
| new DocumentationImpl(context, dependency); |
| } |
| } |
| } |
| |
| private void analyzeDocumentation(File projectFolder) |
| { |
| ClassDoc[] classes = getContext().getRoot().classes(); |
| for (ClassDoc classDoc : classes) |
| { |
| if (classDoc.containingClass() == null) |
| { |
| File file = classDoc.position().file(); |
| if (ArticleUtil.containsFile(projectFolder, file)) |
| { |
| PackageDoc packageDoc = classDoc.containingPackage(); |
| StructuralElement parent = analyzePackage(packageDoc); |
| analyzeClass(parent, classDoc); |
| } |
| } |
| } |
| } |
| |
| private StructuralElement analyzePackage(PackageDoc packageDoc) |
| { |
| if (packageDoc != null) |
| { |
| Object value = getContext().lookup(packageDoc); |
| if (value instanceof Category) |
| { |
| return (Category)value; |
| } |
| |
| PackageDoc parentDoc = ArticleUtil.getParentPackage(getContext().getRoot(), packageDoc); |
| if (ArticleUtil.isDocumented(packageDoc)) |
| { |
| StructuralElement parent = analyzePackage(parentDoc); |
| |
| ClassDoc javadocMarkerClass = packageDoc.findClass(JAVADOC_MARKER_CLASS); |
| if (javadocMarkerClass != null && javadocMarkerClass.isPackagePrivate()) |
| { |
| return new JavadocImpl(parent, packageDoc); |
| } |
| |
| ClassDoc schemadocMarkerClass = packageDoc.findClass(SCHEMADOC_MARKER_CLASS); |
| if (schemadocMarkerClass != null && schemadocMarkerClass.isPackagePrivate()) |
| { |
| return new SchemadocImpl(parent, packageDoc); |
| } |
| |
| return new CategoryImpl(parent, packageDoc); |
| } |
| |
| warnIfSubPackagesUndocumented(packageDoc, parentDoc); |
| } |
| |
| return this; |
| } |
| |
| private void analyzeClass(StructuralElement parent, ClassDoc classDoc) |
| { |
| // TODO Non-public classes? |
| |
| if (ArticleUtil.isIgnore(classDoc)) |
| { |
| return; |
| } |
| |
| if (parent instanceof Javadoc && classDoc.simpleTypeName().equals(JAVADOC_MARKER_CLASS)) |
| { |
| return; |
| } |
| |
| if (parent instanceof Schemadoc && classDoc.simpleTypeName().equals(SCHEMADOC_MARKER_CLASS)) |
| { |
| return; |
| } |
| |
| Tag[] externals = classDoc.tags("@external"); |
| if (externals != null && externals.length != 0) |
| { |
| String url = externals[0].inlineTags()[0].text(); |
| if (URI.createURI(url).isRelative()) |
| { |
| new PluginResourceImpl(parent, classDoc, url); |
| } |
| else |
| { |
| new ExternalArticleImpl(parent, classDoc, url); |
| } |
| |
| return; |
| } |
| |
| if (ArticleUtil.isSnippet(getContext().getRoot(), classDoc)) |
| { |
| new SnippetImpl(this, classDoc); |
| analyzeClassChildren(this, classDoc); |
| } |
| else |
| { |
| Chapter chapter = createChapter(parent, classDoc); |
| analyzeClassChildren(chapter, classDoc); |
| } |
| } |
| |
| private void analyzeClassChildren(StructuralElement parent, ClassDoc classDoc) |
| { |
| for (ClassDoc child : classDoc.innerClasses()) |
| { |
| analyzeClass(parent, child); |
| } |
| |
| for (MethodDoc methodDoc : classDoc.methods()) |
| { |
| analyzeMethod(methodDoc); |
| } |
| } |
| |
| private void analyzeMethod(MethodDoc methodDoc) |
| { |
| if (ArticleUtil.isIgnore(methodDoc)) |
| { |
| return; |
| } |
| |
| if (ArticleUtil.isSnippet(getContext().getRoot(), methodDoc)) |
| { |
| new SnippetImpl(this, methodDoc); |
| } |
| |
| if (ArticleUtil.isFactory(methodDoc)) |
| { |
| new FactoryImpl(this, methodDoc); |
| } |
| } |
| |
| private void warnIfSubPackagesUndocumented(PackageDoc packageDoc, PackageDoc parentDoc) |
| { |
| while (parentDoc != null) |
| { |
| if (ArticleUtil.isDocumented(parentDoc)) |
| { |
| System.err.println("Undocumented category " + packageDoc.name()); |
| break; |
| } |
| |
| parentDoc = ArticleUtil.getParentPackage(getContext().getRoot(), parentDoc); |
| } |
| } |
| |
| private Chapter createChapter(StructuralElement parent, ClassDoc classDoc) |
| { |
| if (parent instanceof Chapter) |
| { |
| return new ChapterImpl(parent, classDoc); |
| } |
| |
| return new ArticleImpl(parent, classDoc); |
| } |
| |
| private void loadPlugins(File projectFolder) |
| { |
| try |
| { |
| Resource resource = AssembleScripts.JavaDoc.getTocXmiResource(projectFolder, false); |
| |
| for (Object content : resource.getContents().toArray()) |
| { |
| getPlugins().add((Plugin)content); |
| } |
| } |
| catch (IOException ex) |
| { |
| ex.printStackTrace(); |
| } |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @Override |
| protected EClass eStaticClass() |
| { |
| return ArticlePackage.Literals.DOCUMENTATION; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| public Context getContext() |
| { |
| if (eContainerFeatureID() != ArticlePackage.DOCUMENTATION__CONTEXT) |
| { |
| return null; |
| } |
| return (Context)eContainer(); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| public NotificationChain basicSetContext(Context newContext, NotificationChain msgs) |
| { |
| msgs = eBasicSetContainer((InternalEObject)newContext, ArticlePackage.DOCUMENTATION__CONTEXT, msgs); |
| return msgs; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| public void setContext(Context newContext) |
| { |
| if (newContext != eInternalContainer() |
| || eContainerFeatureID() != ArticlePackage.DOCUMENTATION__CONTEXT && newContext != null) |
| { |
| if (EcoreUtil.isAncestor(this, newContext)) |
| { |
| throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); |
| } |
| NotificationChain msgs = null; |
| if (eInternalContainer() != null) |
| { |
| msgs = eBasicRemoveFromContainer(msgs); |
| } |
| if (newContext != null) |
| { |
| msgs = ((InternalEObject)newContext).eInverseAdd(this, ArticlePackage.CONTEXT__DOCUMENTATIONS, Context.class, |
| msgs); |
| } |
| msgs = basicSetContext(newContext, msgs); |
| if (msgs != null) |
| { |
| msgs.dispatch(); |
| } |
| } |
| else if (eNotificationRequired()) |
| { |
| eNotify( |
| new ENotificationImpl(this, Notification.SET, ArticlePackage.DOCUMENTATION__CONTEXT, newContext, newContext)); |
| } |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| public EList<EmbeddableElement> getEmbeddableElements() |
| { |
| if (embeddableElements == null) |
| { |
| embeddableElements = new EObjectContainmentWithInverseEList<EmbeddableElement>(EmbeddableElement.class, this, |
| ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS, ArticlePackage.EMBEDDABLE_ELEMENT__DOCUMENTATION); |
| } |
| return embeddableElements; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| public EList<Documentation> getDependencies() |
| { |
| if (dependencies == null) |
| { |
| dependencies = new EObjectEList<Documentation>(Documentation.class, this, |
| ArticlePackage.DOCUMENTATION__DEPENDENCIES); |
| } |
| return dependencies; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| public String getProject() |
| { |
| return project; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| public EList<Plugin> getPlugins() |
| { |
| if (plugins == null) |
| { |
| plugins = new EObjectContainmentEList<Plugin>(Plugin.class, this, ArticlePackage.DOCUMENTATION__PLUGINS); |
| } |
| return plugins; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) |
| { |
| switch (featureID) |
| { |
| case ArticlePackage.DOCUMENTATION__CONTEXT: |
| if (eInternalContainer() != null) |
| { |
| msgs = eBasicRemoveFromContainer(msgs); |
| } |
| return basicSetContext((Context)otherEnd, msgs); |
| case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS: |
| return ((InternalEList<InternalEObject>)(InternalEList<?>)getEmbeddableElements()).basicAdd(otherEnd, msgs); |
| } |
| return super.eInverseAdd(otherEnd, featureID, msgs); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @Override |
| public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) |
| { |
| switch (featureID) |
| { |
| case ArticlePackage.DOCUMENTATION__CONTEXT: |
| return basicSetContext(null, msgs); |
| case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS: |
| return ((InternalEList<?>)getEmbeddableElements()).basicRemove(otherEnd, msgs); |
| case ArticlePackage.DOCUMENTATION__PLUGINS: |
| return ((InternalEList<?>)getPlugins()).basicRemove(otherEnd, msgs); |
| } |
| return super.eInverseRemove(otherEnd, featureID, msgs); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @Override |
| public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) |
| { |
| switch (eContainerFeatureID()) |
| { |
| case ArticlePackage.DOCUMENTATION__CONTEXT: |
| return eInternalContainer().eInverseRemove(this, ArticlePackage.CONTEXT__DOCUMENTATIONS, Context.class, msgs); |
| } |
| return super.eBasicRemoveFromContainerFeature(msgs); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @Override |
| public Object eGet(int featureID, boolean resolve, boolean coreType) |
| { |
| switch (featureID) |
| { |
| case ArticlePackage.DOCUMENTATION__CONTEXT: |
| return getContext(); |
| case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS: |
| return getEmbeddableElements(); |
| case ArticlePackage.DOCUMENTATION__DEPENDENCIES: |
| return getDependencies(); |
| case ArticlePackage.DOCUMENTATION__PROJECT: |
| return getProject(); |
| case ArticlePackage.DOCUMENTATION__PLUGINS: |
| return getPlugins(); |
| } |
| return super.eGet(featureID, resolve, coreType); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public void eSet(int featureID, Object newValue) |
| { |
| switch (featureID) |
| { |
| case ArticlePackage.DOCUMENTATION__CONTEXT: |
| setContext((Context)newValue); |
| return; |
| case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS: |
| getEmbeddableElements().clear(); |
| getEmbeddableElements().addAll((Collection<? extends EmbeddableElement>)newValue); |
| return; |
| case ArticlePackage.DOCUMENTATION__DEPENDENCIES: |
| getDependencies().clear(); |
| getDependencies().addAll((Collection<? extends Documentation>)newValue); |
| return; |
| } |
| super.eSet(featureID, newValue); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @Override |
| public void eUnset(int featureID) |
| { |
| switch (featureID) |
| { |
| case ArticlePackage.DOCUMENTATION__CONTEXT: |
| setContext((Context)null); |
| return; |
| case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS: |
| getEmbeddableElements().clear(); |
| return; |
| case ArticlePackage.DOCUMENTATION__DEPENDENCIES: |
| getDependencies().clear(); |
| return; |
| } |
| super.eUnset(featureID); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @Override |
| public boolean eIsSet(int featureID) |
| { |
| switch (featureID) |
| { |
| case ArticlePackage.DOCUMENTATION__CONTEXT: |
| return getContext() != null; |
| case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS: |
| return embeddableElements != null && !embeddableElements.isEmpty(); |
| case ArticlePackage.DOCUMENTATION__DEPENDENCIES: |
| return dependencies != null && !dependencies.isEmpty(); |
| case ArticlePackage.DOCUMENTATION__PROJECT: |
| return PROJECT_EDEFAULT == null ? project != null : !PROJECT_EDEFAULT.equals(project); |
| case ArticlePackage.DOCUMENTATION__PLUGINS: |
| return plugins != null && !plugins.isEmpty(); |
| } |
| return super.eIsSet(featureID); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> <!-- end-user-doc --> |
| * |
| * @generated |
| */ |
| @Override |
| public String toString() |
| { |
| if (eIsProxy()) |
| { |
| return super.toString(); |
| } |
| |
| StringBuffer result = new StringBuffer(super.toString()); |
| result.append(" (project: "); |
| result.append(project); |
| result.append(')'); |
| return result.toString(); |
| } |
| |
| public File getProjectFolder() |
| { |
| return projectFolder; |
| } |
| |
| @Override |
| public String getBasePathForChildren() |
| { |
| return basePathForChildren; |
| } |
| |
| public boolean isAnalyzed() |
| { |
| return analyzed; |
| } |
| |
| @Override |
| protected String getKind() |
| { |
| return "Documentation"; |
| } |
| |
| public StructuralElement getDefaultElement() |
| { |
| return defaultElement; |
| } |
| |
| public void setDefaultElement(StructuralElement defaultElement) |
| { |
| if (this.defaultElement != null) |
| { |
| throw new AssertionError("Multiple default elements declared in " + getTitle()); |
| } |
| |
| this.defaultElement = defaultElement; |
| } |
| |
| public List<StructuralElement> getNavElements() |
| { |
| return Collections.unmodifiableList(navElements); |
| } |
| |
| @Override |
| public RootDoc getDoc() |
| { |
| return (RootDoc)super.getDoc(); |
| } |
| |
| @Override |
| public Object getId() |
| { |
| return project; |
| } |
| |
| @Override |
| public String getTooltip() |
| { |
| return getTitle(); |
| } |
| |
| @Override |
| public String linkFrom(StructuralElement source) |
| { |
| return defaultElement.linkFrom(source); |
| } |
| |
| @Override |
| protected String getTocHref() |
| { |
| return ((StructuralElementImpl)defaultElement).getTocHref(); |
| } |
| |
| @Override |
| public void generate() throws IOException |
| { |
| EList<StructuralElement> children = getChildren(); |
| if (!children.isEmpty()) |
| { |
| StructuralElement child = children.get(0); |
| File sourceFolder = child.getDoc().position().file().getParentFile(); |
| copyResources(sourceFolder); |
| } |
| |
| super.generate(); |
| |
| generateToc(false); |
| generateToc(true); |
| } |
| |
| @Override |
| protected void generateBreadCrumbs(PrintWriter out, StructuralElement linkSource) throws IOException |
| { |
| super.generateBreadCrumbs(out, linkSource); |
| |
| if (linkSource != this) |
| { |
| generateLink(out, linkSource, null); |
| } |
| } |
| |
| private void generateToc(boolean html) throws IOException |
| { |
| TocWriter writer = null; |
| |
| try |
| { |
| if (html) |
| { |
| writer = new TocWriter.Html(projectFolder); |
| } |
| else |
| { |
| writer = new TocWriter.Xml(projectFolder); |
| } |
| |
| writer.writeGroupStart(getDocumentation().getTitle(), getTocHref(), null); |
| generateTocEntries(writer); |
| writer.writeGroupEnd(); |
| } |
| finally |
| { |
| ArticleUtil.close(writer); |
| } |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public static abstract class TocWriter extends BufferedWriter |
| { |
| protected File project; |
| |
| protected int level; |
| |
| public TocWriter(File project, String filename) throws IOException |
| { |
| super(new FileWriter(new File(LOCAL ? project.getParentFile() : project, filename))); |
| this.project = project; |
| } |
| |
| public final void writePrefix() throws IOException |
| { |
| for (int i = 0; i < level; i++) |
| { |
| write(" "); |
| } |
| } |
| |
| public abstract void writeSingle(String label, String href, String icon) throws IOException; |
| |
| public abstract void writeGroupStart(String label, String href, String icon) throws IOException; |
| |
| public abstract void writeGroupEnd() throws IOException; |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public static class Html extends TocWriter |
| { |
| private int id; |
| |
| private String idPrefix; |
| |
| public Html(File project) throws IOException |
| { |
| super(project, "toc.html"); |
| idPrefix = project.getName().replace('.', '_') + "_"; |
| |
| if (LOCAL) |
| { |
| write("<LINK REL=stylesheet TYPE=\"text/css\" HREF=\"toc.css\">" + NL); |
| write("" + NL); |
| |
| write("<script type=\"text/javascript\">" + NL); |
| write(" function toggle(id)" + NL); |
| write(" {" + NL); |
| write(" e = document.getElementById(id);" + NL); |
| write(" e.style.display = (e.style.display == \"\" ? \"none\" : \"\");" + NL); |
| write(" img = document.getElementById(\"img_\" + id);" + NL); |
| write(" img.src = (e.style.display == \"none\" ? \"plus.gif\" : \"minus.gif\");" + NL); |
| write(" }" + NL); |
| write("</script>" + NL); |
| write("" + NL); |
| |
| write("<font face=\"Segoe UI,Arial\" size=\"-1\">" + NL); |
| write("" + NL); |
| } |
| } |
| |
| @Override |
| public void close() throws IOException |
| { |
| if (LOCAL) |
| { |
| write("" + NL); |
| write("</font>" + NL); |
| } |
| |
| super.close(); |
| } |
| |
| public String nextID() |
| { |
| return idPrefix + ++id; |
| } |
| |
| public void writeHref(String label, String href) throws IOException |
| { |
| label = label.replaceAll(" ", " "); |
| if (level == 0) |
| { |
| label = "<b>" + label + "</b>"; |
| } |
| |
| URI uri = URI.createURI(href); |
| if (uri.isRelative()) |
| { |
| href = project.getName() + "/" + href; |
| } |
| |
| write("<a href=\"" + href + "\" target=\"content\">" + label + "</a>"); |
| } |
| |
| public void writeImage(String name) throws IOException |
| { |
| write("<img src=\"" + name + "\">"); |
| } |
| |
| @Override |
| public void writeSingle(String label, String href, String icon) throws IOException |
| { |
| writePrefix(); |
| write("<div class=\"te\"><span>"); |
| writeImage("empty.gif"); |
| writeImage(icon != null ? icon + ".gif" : "article.gif"); |
| writeHref(label, href); |
| write("</span></div>" + NL); |
| } |
| |
| @Override |
| public void writeGroupStart(String label, String href, String icon) throws IOException |
| { |
| String id = nextID(); |
| |
| writePrefix(); |
| write("<div class=\"te\">"); |
| write("<span><a href=\"javascript:toggle('" + id + "')\">"); |
| write("<img src=\"" + "plus.gif" + "\" id=\"img_" + id + "\">"); |
| write("</a>"); |
| |
| if (level == 0) |
| { |
| writeImage("documentation.gif"); |
| } |
| else |
| { |
| writeImage(icon != null ? icon + ".gif" : "category.gif"); |
| } |
| |
| writeHref(label, href); |
| write("</span></div>" + NL); |
| |
| writePrefix(); |
| write("<div id=\"" + id + "\" style=\"display:none; margin-left:20px;\">" + NL); |
| ++level; |
| } |
| |
| @Override |
| public void writeGroupEnd() throws IOException |
| { |
| --level; |
| writePrefix(); |
| write("</div>" + NL); |
| } |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public static class Xml extends TocWriter |
| { |
| public Xml(File project) throws IOException |
| { |
| super(project, "toc.xml"); |
| write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + NL); |
| write("<?NLS TYPE=\"org.eclipse.help.toc\"?>" + NL + NL); |
| } |
| |
| @Override |
| public void writeSingle(String label, String href, String icon) throws IOException |
| { |
| writePrefix(); |
| write("<topic label=\"" + label + "\" href=\"" + href + "\"" + icon(icon) + " />" + NL); |
| } |
| |
| @Override |
| public void writeGroupStart(String label, String href, String icon) throws IOException |
| { |
| writePrefix(); |
| if (level == 0) |
| { |
| write("<toc label=\"" + label + "\" topic=\"" + href + "\">" + NL); |
| } |
| else |
| { |
| write("<topic label=\"" + label + "\" href=\"" + href + "\"" + icon(icon) + ">" + NL); |
| } |
| |
| ++level; |
| } |
| |
| @Override |
| public void writeGroupEnd() throws IOException |
| { |
| --level; |
| |
| writePrefix(); |
| if (level == 0) |
| { |
| write("</toc>" + NL); |
| } |
| else |
| { |
| write("</topic>" + NL); |
| } |
| } |
| |
| private String icon(String icon) |
| { |
| if (icon == null) |
| { |
| return ""; |
| } |
| |
| return " icon=\"" + icon + "\""; |
| } |
| } |
| } |
| } // DocumentationImpl |