1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.form.field.factory;
35
36 import static com.google.common.base.Enums.getIfPresent;
37 import static org.apache.commons.io.FilenameUtils.getExtension;
38 import static org.apache.commons.lang3.StringUtils.isNotBlank;
39 import static org.vaadin.v7.aceeditor.AceMode.forFileEnding;
40
41 import info.magnolia.context.MgnlContext;
42 import info.magnolia.objectfactory.Components;
43 import info.magnolia.ui.api.context.UiContext;
44 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
45 import info.magnolia.ui.form.field.definition.CodeFieldDefinition;
46
47 import javax.inject.Inject;
48
49 import org.vaadin.v7.aceeditor.AceEditor;
50 import org.vaadin.v7.aceeditor.AceMode;
51
52 import com.google.common.base.Optional;
53 import com.vaadin.server.Sizeable;
54 import com.vaadin.v7.data.Item;
55 import com.vaadin.v7.data.Property;
56 import com.vaadin.v7.event.FieldEvents.TextChangeEvent;
57 import com.vaadin.v7.event.FieldEvents.TextChangeListener;
58 import com.vaadin.v7.ui.Field;
59
60
61
62
63 public class CodeFieldFactory extends AbstractFieldFactory<CodeFieldDefinition, String> {
64
65 private static final String FREEMARKER_LANGUAGE = "freemarker";
66 private static final String ACE_EDITOR_FTL_ID = "ftl";
67 private static final String ACE_EDITOR_RESOURCES = "/.resources/ace/";
68
69 private AceEditor field;
70
71 @Inject
72 public CodeFieldFactory(CodeFieldDefinition definition, Item relatedFieldItem, UiContext uiContext, I18NAuthoringSupport i18nAuthoringSupport) {
73 super(definition, relatedFieldItem, uiContext, i18nAuthoringSupport);
74 }
75
76
77
78
79 @Deprecated
80 public CodeFieldFactory(CodeFieldDefinition definition, Item relatedFieldItem) {
81 this(definition, relatedFieldItem, null, Components.getComponent(I18NAuthoringSupport.class));
82 }
83
84 @Override
85 protected Field<String> createFieldComponent() {
86 field = newAceEditor();
87
88
89 field.addTextChangeListener(createTextChangeListener(field));
90
91 field.setStyleName("textcodefield");
92 field.setUseWorker(false);
93
94 return field;
95 }
96
97
98
99
100 protected AceEditor newAceEditor() {
101 AceEditor aceEditor = new AceEditor();
102 if (MgnlContext.isWebContext()) {
103 String aceEditorResourcePath = MgnlContext.getContextPath() + ACE_EDITOR_RESOURCES;
104 aceEditor.setModePath(aceEditorResourcePath);
105 aceEditor.setWorkerPath(aceEditorResourcePath);
106 aceEditor.setThemePath(aceEditorResourcePath);
107 }
108
109 if (isNotBlank(definition.getLanguage())) {
110 aceEditor.setMode(getModeType(definition.getLanguage()));
111 } else if (isNotBlank(definition.getFileNameProperty())) {
112 Property<?> fileNameProperty = item.getItemProperty(definition.getFileNameProperty());
113 if (fileNameProperty != null) {
114 String fileName = String.valueOf(fileNameProperty.getValue());
115 String extension = getExtension(fileName);
116 AceMode mode = getAceModeByFileExtension(extension);
117 if (mode != null) {
118 aceEditor.setMode(mode);
119 }
120 }
121 }
122 if (definition.getHeight() > 0) {
123 aceEditor.setHeight(definition.getHeight(), Sizeable.Unit.PIXELS);
124 }
125 return aceEditor;
126 }
127
128
129
130
131
132 private TextChangeListener createTextChangeListener(final AceEditor field) {
133 return new TextChangeListener() {
134
135 @SuppressWarnings("unchecked")
136 @Override
137 public void textChange(TextChangeEvent event) {
138 field.getPropertyDataSource().setValue(event.getText());
139 }
140 };
141 }
142
143
144
145
146
147
148
149 private String getModeType(String language) {
150 return FREEMARKER_LANGUAGE.equals(language) ? ACE_EDITOR_FTL_ID : language;
151 }
152
153
154
155
156
157
158 private AceMode getAceModeByFileExtension(String extension) {
159
160 Optional<AceMode> aceModeValue = getIfPresent(AceMode.class, extension);
161 if (aceModeValue.isPresent()) {
162 return aceModeValue.get();
163 } else {
164
165 AceMode aceMode = forFileEnding(extension);
166 return aceMode != null ? aceMode : null;
167 }
168 }
169
170 }