001package org.nasdanika.html.model.app.graph;
002
003import java.util.Collection;
004
005import org.eclipse.emf.common.util.URI;
006import org.nasdanika.common.ProgressMonitor;
007import org.nasdanika.common.Supplier;
008import org.nasdanika.graph.Connection;
009import org.nasdanika.html.model.app.Label;
010
011/**
012 * Creates labels, links for cross-referencing, and other "widgets".
013 * @author Pavel
014 *
015 */
016public interface WidgetFactory {
017        
018        /**
019         * Functional interface for selectors to which factories delegate widget creation.
020         * {@link Connection} {@link WidgetFactory} shall not delegate to Selector, but rather to ConnectionSelector 
021         */
022        interface Selector<T> {
023        
024                /**
025                 * Creates a widget.   
026                 * @param widgetFactory
027                 * @param base For connections, if not null, is resolved against the calling end URI - source or target, if it is not null. 
028                 * If null, the respective end URI is used as the base.
029                 * @param progressMonitor
030                 * @return A widget or null
031                 */             
032                T createWidget(WidgetFactory widgetFactory, URI base, ProgressMonitor progressMonitor); 
033                
034        }
035        
036        /**
037         * A maker interface indicating that {@link Connection} {@link WidgetFactory} shall delegate to this selector instead of passing it to the other end's node.
038         * @param <T>
039         */
040        interface ConnectionSelector<T> extends Selector<T> {
041                
042        }
043        
044        /**
045         * Creates a "label" which is an HTML/text representation of something which does not navigate to that something. E.g. {@link Label}. Can be composite.
046         * @return
047         */
048        Object createLabel(ProgressMonitor progressMonitor);
049        
050        /**
051         * Creates a string (HTML text) representation of "label".
052         * @return
053         */
054        String createLabelString(ProgressMonitor progressMonitor);
055        
056        /**
057         * Creates a link if possible or a label.
058         * Calls createLink(null, progressMonitor) 
059         * @return
060         */
061        default Object createLink(ProgressMonitor progressMonitor) {
062                return createLink(null, progressMonitor);
063        }
064        
065        /**
066         * Creates a link with URL's deresolved (relativized) against the provided base URI.
067         * 
068         * @param base For connections, if not null, is resolved against the calling end URI - source or target, if it is not null. 
069         * If null, the respective end URI is used as the base.
070         * @param progressMonitor
071         * @return
072         */
073        Object createLink(URI base, ProgressMonitor progressMonitor);
074        
075        /**
076         * Link rendered to String
077         * @param progressMonitor
078         * @return
079         */
080        default String createLinkString(ProgressMonitor progressMonitor) {
081                return createLinkString(null, progressMonitor);
082        }
083        
084        /**
085         * Link rendered to String
086         * @param base
087         * @param progressMonitor
088         * @return
089         */
090        String createLinkString(URI base, ProgressMonitor progressMonitor);
091        
092        /**
093         * Calls createWidget(selector, null, progressMonitor).
094         * For connections URL's in the link are deresolved (relativized) against the calling end URI - source or target, if it is not null.
095         * @param selector
096         * @param progressMonitor
097         * @return
098         */
099        default Object createWidget(Object selector, ProgressMonitor progressMonitor) {
100                return createWidget(selector, null, progressMonitor);
101        }
102
103        /**
104         * Creates a widget for an aspect (feature) of the object identified by the selector, which can be a {@link Selector}.   
105         * @param selector Aspect/feature key. If an instasnce of Selector, then the factory delegates widget creation to the selector passing itself as an argument.
106         * @param base For connections, if not null, is resolved against the calling end URI - source or target, if it is not null. 
107         * If null, the respective end URI is used as the base.
108         * @param progressMonitor
109         * @return A widget or null
110         */
111        default Object createWidget(Object selector, URI base, ProgressMonitor progressMonitor) {
112                if (selector instanceof Selector) {
113                        return createWidget((Selector<?>) selector, base, progressMonitor);
114                }
115                return null;
116        }
117        
118        default <T> T createWidget(Selector<T> selector, URI base, ProgressMonitor progressMonitor) {
119                return selector.createWidget(this, base, progressMonitor);
120        }       
121        
122        default <T> T createWidget(Selector<T> selector, ProgressMonitor progressMonitor) {
123                return createWidget(selector, null, progressMonitor);
124        }       
125
126        /**
127         * Calls createWidgetString(selector, null, progressMonitor)
128         * @param selector
129         * @param progressMonitor
130         * @return
131         */
132        default String createWidgetString(Object selector, ProgressMonitor progressMonitor) {
133                return createWidgetString(selector, null, progressMonitor);
134        }
135
136        /**
137         * @param selector
138         * @param base
139         * @param progressMonitor
140         * @return widget rendered to (HTML) string
141         */
142        String createWidgetString(Object selector, URI base, ProgressMonitor progressMonitor);
143        
144        /**
145         * Used to establish node URI's. Propagates caller URI.
146         * @param base
147         */
148        void resolve(URI base, ProgressMonitor progressMonitor);
149        
150        Supplier<Collection<Label>> createLabelsSupplier();
151
152}