Skip to content

Commit a121396

Browse files
committed
Container/row/column
1 parent 324823e commit a121396

8 files changed

Lines changed: 411 additions & 82 deletions

File tree

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package org.nasdanika.models.bootstrap.producer;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.Map.Entry;
9+
import java.util.concurrent.ConcurrentHashMap;
10+
import java.util.function.BiConsumer;
11+
import java.util.function.Consumer;
12+
13+
import org.eclipse.emf.ecore.EObject;
14+
import org.nasdanika.common.Context;
15+
import org.nasdanika.common.ProgressMonitor;
16+
import org.nasdanika.html.Container;
17+
import org.nasdanika.html.HTMLElement;
18+
import org.nasdanika.html.Producer;
19+
import org.nasdanika.models.bootstrap.Appearance;
20+
import org.nasdanika.models.bootstrap.BootstrapElement;
21+
22+
import reactor.core.publisher.Mono;
23+
24+
public class BootstrapElementProducer<T extends BootstrapElement, D extends org.nasdanika.html.bootstrap.BootstrapElement<?, ?>> implements Producer<Object> {
25+
26+
protected T element;
27+
protected D delegate;
28+
29+
protected Consumer<Object> builder;
30+
31+
public static Producer<Object> createProxyProducer(EObject element, BiConsumer<EObject, BiConsumer<Producer<Object>, ProgressMonitor>> elementProvider) {
32+
return new Producer<Object>() {
33+
34+
private Producer<Object> cDelegate;
35+
36+
{
37+
elementProvider.accept(element, (cp, pm) -> cDelegate = cp);
38+
}
39+
40+
@Override
41+
public Mono<Object> produceAsync(int indent) {
42+
return cDelegate.produceAsync(indent);
43+
}
44+
45+
@Override
46+
public Object produce(int indent) {
47+
return cDelegate.produce(indent);
48+
}
49+
50+
@Override
51+
public void build(Object obj) {
52+
cDelegate.build(obj);
53+
}
54+
55+
};
56+
}
57+
58+
public static List<Producer<Object>> createProxyProducers(Collection<? extends EObject> elements, BiConsumer<EObject, BiConsumer<Producer<Object>, ProgressMonitor>> elementProvider) {
59+
return elements
60+
.stream()
61+
.map(e -> createProxyProducer(e, elementProvider))
62+
.toList();
63+
}
64+
65+
protected D createDelegate(T element, Context context) {
66+
return null;
67+
}
68+
69+
protected Map<String,Producer<?>> attributeProducers = new ConcurrentHashMap<>();
70+
protected Collection<Producer<?>> contentProducers = Collections.synchronizedCollection(new ArrayList<>());
71+
protected AppearanceBuilder appearanceBuilder;
72+
73+
protected BootstrapElementProducer(
74+
Context context,
75+
T element,
76+
BiConsumer<EObject, BiConsumer<Producer<Object>, ProgressMonitor>> elementProvider) {
77+
78+
this.element = element;
79+
delegate = createDelegate(element, context);
80+
HTMLElement<?> delegateHtmlElement = delegate == null ? null : delegate.toHTMLElement();
81+
82+
for (Entry<String, EObject> attr: element.getAttributes().entrySet()) {
83+
elementProvider.accept(attr.getValue(), (ap, pm) -> {
84+
if (delegateHtmlElement != null) {
85+
delegateHtmlElement.attribute(attr.getKey(), ap);
86+
}
87+
attributeProducers.put(attr.getKey(), ap);
88+
});
89+
}
90+
91+
for (EObject ce: element.getContent()) {
92+
Producer<Object> proxyProducer = createProxyProducer(ce, elementProvider);
93+
if (delegateHtmlElement instanceof Container) {
94+
((Container<?>) delegateHtmlElement).content(proxyProducer);
95+
}
96+
contentProducers.add(proxyProducer);
97+
}
98+
99+
Appearance appearance = element.getAppearance();
100+
if (appearance != null) {
101+
for (Entry<String, EObject> attr: appearance.getAttributes().entrySet()) {
102+
elementProvider.accept(attr.getValue(), (ap, pm) -> {
103+
if (delegateHtmlElement != null) {
104+
delegateHtmlElement.attribute(attr.getKey(), ap);
105+
}
106+
attributeProducers.put(attr.getKey(), ap);
107+
});
108+
}
109+
appearanceBuilder = new AppearanceBuilder(appearance);
110+
appearanceBuilder.build(delegate.toHTMLElement());
111+
}
112+
}
113+
114+
@Override
115+
public void build(Object obj) {
116+
HTMLElement<?> delegateHtmlElement = ((org.nasdanika.html.bootstrap.BootstrapElement<?,?>) obj).toHTMLElement();
117+
attributeProducers.forEach((k,v) -> delegateHtmlElement.attribute(k, k));
118+
if (appearanceBuilder != null) {
119+
appearanceBuilder.build(delegateHtmlElement);
120+
}
121+
for (Producer<?> cp: contentProducers) {
122+
if (delegateHtmlElement instanceof Container) {
123+
((Container<?>) delegateHtmlElement).content(cp);
124+
}
125+
}
126+
}
127+
128+
@Override
129+
public Mono<Object> produceAsync(int indent) {
130+
return delegate.produceAsync(indent);
131+
}
132+
133+
@Override
134+
public Object produce(int indent) {
135+
return delegate.produce(indent);
136+
}
137+
138+
}

producer/src/main/java/org/nasdanika/models/bootstrap/producer/BootstraphProducerFactory.java

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ public BootstraphProducerFactory(Context context) {
1717
this.context = context;
1818
}
1919

20+
@org.nasdanika.common.Transformer.Factory
21+
public final Producer<String> createPageProducer(
22+
org.nasdanika.models.bootstrap.Page page,
23+
boolean parallel,
24+
BiConsumer<EObject, BiConsumer<Producer<Object>,ProgressMonitor>> elementProvider,
25+
Consumer<BiConsumer<Map<EObject, Producer<Object>>,ProgressMonitor>> registry,
26+
ProgressMonitor progressMonitor) {
27+
28+
return new PageProducer(context, page, elementProvider);
29+
}
30+
2031
@org.nasdanika.common.Transformer.Factory
2132
public final Producer<Object> createTagProducer(
2233
org.nasdanika.models.bootstrap.Tag tag,
@@ -28,31 +39,65 @@ public final Producer<Object> createTagProducer(
2839
return new TagProducer(context, tag, elementProvider);
2940
}
3041

31-
// BootstrapElement.java
32-
// Tag.java
33-
// Div.java
42+
@org.nasdanika.common.Transformer.Factory
43+
public final Producer<Object> createContainerProducer(
44+
org.nasdanika.models.bootstrap.Container container,
45+
boolean parallel,
46+
BiConsumer<EObject, BiConsumer<Producer<Object>,ProgressMonitor>> elementProvider,
47+
Consumer<BiConsumer<Map<EObject, Producer<Object>>,ProgressMonitor>> registry,
48+
ProgressMonitor progressMonitor) {
49+
50+
return new ContainerProducer(context, container, elementProvider);
51+
}
3452

53+
@org.nasdanika.common.Transformer.Wire
54+
public final void wireContainerRows(
55+
org.nasdanika.models.bootstrap.Container container,
56+
ContainerProducer containerProducer,
57+
Map<?,?> registry,
58+
int pass,
59+
ProgressMonitor progressMonitor) {
60+
61+
containerProducer.buildDelegateRows();
62+
}
3563

64+
@org.nasdanika.common.Transformer.Factory
65+
public final Producer<Object> createRowProducer(
66+
org.nasdanika.models.bootstrap.Row row,
67+
boolean parallel,
68+
BiConsumer<EObject, BiConsumer<Producer<Object>,ProgressMonitor>> elementProvider,
69+
Consumer<BiConsumer<Map<EObject, Producer<Object>>,ProgressMonitor>> registry,
70+
ProgressMonitor progressMonitor) {
71+
72+
return new RowProducer(context, row, elementProvider);
73+
}
74+
75+
@org.nasdanika.common.Transformer.Factory
76+
public final Producer<Object> createColumnProducer(
77+
org.nasdanika.models.bootstrap.Column column,
78+
boolean parallel,
79+
BiConsumer<EObject, BiConsumer<Producer<Object>,ProgressMonitor>> elementProvider,
80+
Consumer<BiConsumer<Map<EObject, Producer<Object>>,ProgressMonitor>> registry,
81+
ProgressMonitor progressMonitor) {
82+
83+
return new ColumnProducer(context, column, elementProvider);
84+
}
85+
3686
// Accordion.java
3787
// ActionGroup.java
3888
// ActionGroupItem.java
3989
// Alert.java
40-
// Appearance.java
4190
// Badge.java
42-
// Border.java
4391
// Breadcrumb.java
4492
// Button.java
4593
// ButtonGroup.java
4694
// ButtonToolbar.java
4795
// Card.java
4896
// Carousel.java
4997
// Collapse.java
50-
// Column.java
5198
// ColumnWidth.java
52-
// Container.java
5399
// ContentActionGroupItem.java
54100
// Dropdown.java
55-
// Float.java
56101
// Form.java
57102
// FormGroup.java
58103
// InputGroup.java
@@ -63,17 +108,14 @@ public final Producer<Object> createTagProducer(
63108
// Navbar.java
64109
// Navs.java
65110
// Page.java
66-
// Row.java
67111
// Slide.java
68-
// Spacing.java
69112
// Table.java
70113
// TableCell.java
71114
// TableConfiguration.java
72115
// TableHeader.java
73116
// TableRow.java
74117
// TableRowContainer.java
75118
// TableSection.java
76-
// Text.java
77119
// Tooltip.java
78120

79121
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.nasdanika.models.bootstrap.producer;
2+
3+
import java.util.function.BiConsumer;
4+
5+
import org.eclipse.emf.ecore.EObject;
6+
import org.nasdanika.common.Context;
7+
import org.nasdanika.common.ProgressMonitor;
8+
import org.nasdanika.html.Producer;
9+
import org.nasdanika.html.bootstrap.Breakpoint;
10+
import org.nasdanika.html.bootstrap.Container;
11+
import org.nasdanika.html.bootstrap.Size;
12+
import org.nasdanika.models.bootstrap.Column;
13+
import org.nasdanika.models.bootstrap.ColumnWidth;
14+
15+
public class ColumnProducer extends BootstrapElementProducer<Column, org.nasdanika.html.bootstrap.Container.Row.Col> {
16+
17+
protected ColumnProducer(
18+
Context context,
19+
Column element,
20+
BiConsumer<EObject, BiConsumer<Producer<Object>, ProgressMonitor>> elementProvider) {
21+
super(context, element, elementProvider);
22+
}
23+
24+
@Override
25+
public void build(Object obj) {
26+
super.build(obj);
27+
for (ColumnWidth cw: element.getWidth()) {
28+
((Container.Row.Col) obj).width(Breakpoint.valueOf(cw.getBreakpoint()), Size.valueOf(cw.getWidth()));
29+
}
30+
}
31+
32+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.nasdanika.models.bootstrap.producer;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Collections;
6+
import java.util.function.BiConsumer;
7+
8+
import org.eclipse.emf.ecore.EObject;
9+
import org.nasdanika.common.Context;
10+
import org.nasdanika.common.ProgressMonitor;
11+
import org.nasdanika.html.Producer;
12+
import org.nasdanika.html.bootstrap.BootstrapFactory;
13+
import org.nasdanika.models.bootstrap.Container;
14+
import org.nasdanika.models.bootstrap.Row;
15+
16+
public class ContainerProducer extends BootstrapElementProducer<Container, org.nasdanika.html.bootstrap.Container> {
17+
18+
protected Collection<Producer<?>> rowBuilders = Collections.synchronizedCollection(new ArrayList<>());
19+
20+
protected ContainerProducer(
21+
Context context,
22+
Container element,
23+
BiConsumer<EObject, BiConsumer<Producer<Object>, ProgressMonitor>> elementProvider) {
24+
super(context, element, elementProvider);
25+
26+
for (Row row: element.getRows()) {
27+
rowBuilders.add(createProxyProducer(row, elementProvider));
28+
}
29+
}
30+
31+
@Override
32+
protected org.nasdanika.html.bootstrap.Container createDelegate(Container element, Context context) {
33+
BootstrapFactory bootstrapFactory = context.get(BootstrapFactory.class, BootstrapFactory.INSTANCE);
34+
return element.isFluid() ? bootstrapFactory.fluidContainer() : bootstrapFactory.container();
35+
}
36+
37+
@Override
38+
public void build(Object obj) {
39+
super.build(obj);
40+
if (obj instanceof org.nasdanika.html.bootstrap.Container) {
41+
for (Producer<?> rb: rowBuilders) {
42+
rb.build(((org.nasdanika.html.bootstrap.Container) obj).row());
43+
}
44+
}
45+
}
46+
47+
public void buildDelegateRows() {
48+
for (Producer<?> rb: rowBuilders) {
49+
rb.build(((org.nasdanika.html.bootstrap.Container) delegate).row());
50+
}
51+
}
52+
53+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.nasdanika.models.bootstrap.producer;
2+
3+
import java.util.function.BiConsumer;
4+
5+
import org.eclipse.emf.ecore.EObject;
6+
import org.nasdanika.common.Context;
7+
import org.nasdanika.common.ProgressMonitor;
8+
import org.nasdanika.html.Producer;
9+
import org.nasdanika.html.bootstrap.BootstrapFactory;
10+
import org.nasdanika.html.bootstrap.Theme;
11+
import org.nasdanika.models.bootstrap.Page;
12+
13+
public class PageProducer extends org.nasdanika.models.html.producer.PageProducer {
14+
15+
public PageProducer(
16+
Context context,
17+
Page page,
18+
BiConsumer<EObject, BiConsumer<Producer<Object>, ProgressMonitor>> elementProvider) {
19+
20+
super(context, page, elementProvider);
21+
22+
Theme theme = page.getTheme();
23+
if (theme == null && page.isCdn()) {
24+
theme = Theme.Default;
25+
}
26+
if (theme != null) {
27+
BootstrapFactory.INSTANCE.bootstrapCdnHTMLPage(delegate, org.nasdanika.html.bootstrap.Theme.valueOf(theme.name()));
28+
}
29+
}
30+
31+
}

0 commit comments

Comments
 (0)