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.dam.app.ui.field.factory;
35
36 import info.magnolia.dam.api.Asset;
37 import info.magnolia.dam.api.AssetProviderRegistry;
38 import info.magnolia.dam.api.DamException;
39 import info.magnolia.dam.api.ItemKey;
40 import info.magnolia.dam.jcr.DamConstants;
41 import info.magnolia.i18nsystem.SimpleTranslator;
42 import info.magnolia.link.LinkException;
43 import info.magnolia.link.LinkUtil;
44 import info.magnolia.objectfactory.Components;
45 import info.magnolia.ui.api.app.AppController;
46 import info.magnolia.ui.api.app.ChooseDialogCallback;
47 import info.magnolia.ui.api.context.UiContext;
48 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
49 import info.magnolia.ui.form.field.definition.RichTextFieldDefinition;
50 import info.magnolia.ui.form.field.factory.RichTextFieldFactory;
51 import info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector;
52 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeItemId;
53 import info.magnolia.ui.vaadin.richtext.MagnoliaRichTextField;
54 import info.magnolia.ui.vaadin.richtext.MagnoliaRichTextFieldConfig;
55
56 import java.util.Locale;
57 import java.util.regex.Matcher;
58
59 import javax.inject.Inject;
60
61 import org.apache.commons.lang3.StringUtils;
62
63 import com.google.gson.Gson;
64 import com.vaadin.server.VaadinService;
65 import com.vaadin.ui.UI;
66 import com.vaadin.v7.data.Item;
67 import com.vaadin.v7.data.util.converter.Converter;
68 import com.vaadin.v7.ui.Field;
69
70
71
72
73
74
75 public class AssetsEnabledRichTextFieldFactory extends RichTextFieldFactory {
76
77 private static final String FILE_BROWSER_PLUGIN = "magnoliaFileBrowser";
78
79 private static final String FILE_BROWSER_PLUGIN_CHOOSE_ASSET_EVENT = "chooseAsset";
80
81 public static final String ASSET_CHOSEN_EVENT_ID = "assetChosen";
82
83 private AssetProviderRegistry assetProviderRegistry;
84
85 @Inject
86 public AssetsEnabledRichTextFieldFactory(RichTextFieldDefinition definition, Item relatedFieldItem, UiContext uiContext, I18NAuthoringSupport i18nAuthoringSupport, AppController appController, SimpleTranslator i18n, AssetProviderRegistry assetProviderRegistry) {
87 super(definition, relatedFieldItem, uiContext, i18nAuthoringSupport, appController, i18n);
88 this.assetProviderRegistry = assetProviderRegistry;
89 }
90
91
92
93
94 @Deprecated
95 public AssetsEnabledRichTextFieldFactory(RichTextFieldDefinition definition, Item relatedFieldItem, AppController appController, UiContext uiContext, SimpleTranslator i18n, AssetProviderRegistry assetProviderRegistry) {
96 this(definition, relatedFieldItem, uiContext, Components.getComponent(I18NAuthoringSupport.class), appController, i18n, assetProviderRegistry);
97 }
98
99
100
101
102 @Deprecated
103 public AssetsEnabledRichTextFieldFactory(RichTextFieldDefinition definition, Item relatedFieldItem, AppController appController, UiContext uiContext, SimpleTranslator i18n, AssetProviderRegistry assetProviderRegistry, ContentConnector contentConnector) {
104 this(definition, relatedFieldItem, uiContext, Components.getComponent(I18NAuthoringSupport.class), appController, i18n, assetProviderRegistry);
105 }
106
107 @Override
108 protected Field<String> createFieldComponent() {
109 MagnoliaRichTextField field = (MagnoliaRichTextField) super.createFieldComponent();
110 if (definition.isImages() || StringUtils.isNotBlank(definition.getConfigJsFile())) {
111
112 field.addListener(new MagnoliaRichTextField.PluginListener() {
113 @Override
114 public void onPluginEvent(String eventName, String value) {
115 if (eventName.equals(FILE_BROWSER_PLUGIN_CHOOSE_ASSET_EVENT)) {
116 UI.getCurrent().addStyleName("ui-overlapping-ck-editor");
117 chooseAsset();
118 }
119 }
120 });
121
122 field.setConverter(new Converter<String, String>() {
123 @Override
124 public String convertToModel(String value, Class<? extends String> targetType, Locale locale) throws ConversionException {
125 return LinkUtil.convertAbsoluteLinksToUUIDs(value);
126 }
127
128 @Override
129 public String convertToPresentation(String value, Class<? extends String> targetType, Locale locale) throws ConversionException {
130 if (value != null) {
131
132
133 try {
134 Matcher matcher = LinkUtil.IMAGE_PATTERN.matcher(value);
135 while (matcher.find()) {
136 value = value.replace(matcher.group(), LinkUtil.convertLinksFromUUIDPattern(matcher.group()));
137 }
138 return value;
139 } catch (LinkException e) {
140 return StringUtils.EMPTY;
141 }
142 }
143 return StringUtils.EMPTY;
144 }
145
146 @Override
147 public Class<String> getModelType() {
148 return String.class;
149 }
150
151 @Override
152 public Class<String> getPresentationType() {
153 return String.class;
154 }
155 });
156 }
157 return field;
158 }
159
160 private void chooseAsset() {
161 appController.openChooseDialog("assets", uiContext, null, new ChooseDialogCallback() {
162 @Override
163 public void onItemChosen(String actionName, Object chosenValue) {
164 UI.getCurrent().removeStyleName("ui-overlapping-ck-editor");
165
166 Gson gson = new Gson();
167 String eventJson = "{}";
168 Asset asset;
169
170 try {
171 if (!(chosenValue instanceof JcrNodeItemId)) {
172 return;
173 }
174 asset = assetProviderRegistry.getProviderById(DamConstants.DEFAULT_JCR_PROVIDER_ID).getAsset(new ItemKey(DamConstants.DEFAULT_JCR_PROVIDER_ID, ((JcrNodeItemId) chosenValue).getUuid()));
175 if (asset != null && asset.getMimeType().matches("image.*")) {
176 eventJson = gson.toJson(new FileBrowserUrlDTO(asset.getLink()));
177 } else {
178 eventJson = gson.toJson(new FileBrowserUrlDTO("", "Selected asset is not an image"));
179 }
180 } catch (DamException e) {
181 eventJson = gson.toJson(new FileBrowserUrlDTO("", e.getMessage()));
182 } finally {
183 richTextEditor.firePluginEvent(ASSET_CHOSEN_EVENT_ID, eventJson);
184 }
185 }
186
187
188 @Override
189 public void onCancel() {
190 UI.getCurrent().removeStyleName("ui-overlapping-ck-editor");
191 }
192 });
193 }
194
195 @Override
196 protected MagnoliaRichTextFieldConfig initializeCKEditorConfig() {
197 MagnoliaRichTextFieldConfig config = super.initializeCKEditorConfig();
198
199
200 boolean isCustomConfig = StringUtils.isNotBlank(definition.getConfigJsFile());
201 if (definition.isImages() || isCustomConfig) {
202
203
204 String path = VaadinService.getCurrentRequest().getContextPath();
205 config.addExternalPlugin(FILE_BROWSER_PLUGIN, path + "/VAADIN/js/filebrowser/");
206 config.addListenedEvent(FILE_BROWSER_PLUGIN_CHOOSE_ASSET_EVENT);
207 if (!isCustomConfig) {
208 config.addToExtraPlugins(FILE_BROWSER_PLUGIN);
209 }
210
211
212 config.setFilebrowserImageBrowseLinkUrl("dummy");
213 config.setFilebrowserImageBrowseUrl("dummy");
214 }
215 return config;
216 }
217
218
219
220
221 public static class FileBrowserUrlDTO {
222 public String url;
223 public String errorMessage;
224
225 public FileBrowserUrlDTO(String url, String errorMessage) {
226 this.url = url;
227 this.errorMessage = errorMessage;
228 }
229
230 public FileBrowserUrlDTO(String url) {
231 this(url, null);
232 }
233 }
234 }