001/*
002 * (C) Copyright 2006 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.project.sample;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.HashSet;
025import java.util.LinkedList;
026import java.util.List;
027import java.util.Random;
028import java.util.Set;
029
030import javax.faces.application.FacesMessage;
031import javax.faces.component.EditableValueHolder;
032import javax.faces.component.UIComponent;
033import javax.faces.context.FacesContext;
034import javax.faces.model.SelectItem;
035
036import org.apache.commons.logging.Log;
037import org.apache.commons.logging.LogFactory;
038import org.jboss.seam.ScopeType;
039import org.jboss.seam.annotations.In;
040import org.jboss.seam.annotations.Name;
041import org.jboss.seam.annotations.Observer;
042import org.jboss.seam.annotations.Scope;
043import org.jboss.seam.annotations.remoting.WebRemote;
044import org.jboss.seam.core.Events;
045import org.jboss.seam.faces.FacesMessages;
046import org.nuxeo.ecm.core.api.CoreSession;
047import org.nuxeo.ecm.core.api.DocumentModel;
048import org.nuxeo.ecm.core.api.DocumentModelList;
049import org.nuxeo.ecm.directory.Session;
050import org.nuxeo.ecm.directory.api.DirectoryService;
051import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
052import org.nuxeo.ecm.platform.ui.web.api.WebActions;
053import org.nuxeo.ecm.webapp.helpers.EventNames;
054import org.nuxeo.ecm.webapp.helpers.ResourcesAccessor;
055import org.nuxeo.runtime.api.Framework;
056
057@Scope(ScopeType.CONVERSATION)
058@Name("bookManager")
059public class BookManagerBean implements BookManager, Serializable {
060
061    private static final long serialVersionUID = 1L;
062
063    private static final Log log = LogFactory.getLog(BookManagerBean.class);
064
065    @In(create = true)
066    protected transient NavigationContext navigationContext;
067
068    @In(create = true)
069    protected transient WebActions webActions;
070
071    @In(create = true)
072    protected transient CoreSession documentManager;
073
074    @In(create = true)
075    protected transient FacesMessages facesMessages;
076
077    @In(create = true)
078    protected transient ResourcesAccessor resourcesAccessor;
079
080    private String firstName;
081
082    private String lastName;
083
084    private String isbn;
085
086    private List<String> keywords;
087
088    protected List<SelectItem> keywordList;
089
090    private String page;
091
092    private int rating;
093
094    private String filter;
095
096    public String getParentTitle() {
097        DocumentModel doc = navigationContext.getCurrentDocument();
098        DocumentModel parent = documentManager.getParentDocument(doc.getRef());
099        return (String) parent.getProperty("dublincore", "title");
100    }
101
102    public String getFirstName() {
103        if (firstName == null) {
104            firstName = "";
105        }
106        return firstName;
107    }
108
109    public void setFirstName(String s) {
110        firstName = s;
111    }
112
113    public String getLastName() {
114        if (lastName == null) {
115            lastName = "";
116        }
117        return lastName;
118    }
119
120    public void setLastName(String s) {
121        lastName = s;
122    }
123
124    public String getIsbn() {
125        if (isbn == null) {
126            return "";
127        } else {
128            return isbn;
129        }
130    }
131
132    public void setIsbn(String s) {
133        isbn = s;
134    }
135
136    public int getRating() {
137        return rating;
138    }
139
140    public void setRating(int rating) {
141        this.rating = rating;
142    }
143
144    public List<String> getKeywords() {
145        return keywords;
146    }
147
148    public void setKeywords(List<String> keywords) {
149        this.keywords = keywords;
150    }
151
152    public List<SelectItem> getAvailableKeywords() {
153        if (keywordList == null) {
154            computeKeywordValues();
155        }
156        return keywordList;
157    }
158
159    @Observer(value = { EventNames.DOCUMENT_SELECTION_CHANGED }, create = false)
160    public void resetKeywordValues() {
161        keywordList = null;
162    }
163
164    private void computeKeywordValues() {
165        DirectoryService dirService = Framework.getLocalService(DirectoryService.class);
166
167        try (Session dir = dirService.open("book_keywords")) {
168            DocumentModelList entries = dir.getEntries();
169            keywordList = new ArrayList<SelectItem>(entries.size());
170            for (DocumentModel e : entries) {
171                String value = (String) e.getProperty("vocabulary", "id");
172                String label = (String) e.getProperty("vocabulary", "label");
173                SelectItem item = new SelectItem(value, label);
174                keywordList.add(item);
175            }
176        }
177    }
178
179    private static Random rand = new Random();
180
181    protected static String[] FIRSTNAMES = { "Steve", "John", "Raoul", "James" };
182
183    protected static String[] LASTNAMES = { "Bond", "Einstein", "Tanaka", "Presley" };
184
185    public void randomFirstName() {
186        firstName = FIRSTNAMES[rand.nextInt(FIRSTNAMES.length)];
187    }
188
189    public void randomLastName() {
190        lastName = LASTNAMES[rand.nextInt(LASTNAMES.length)];
191    }
192
193    /*
194     * Validation / change
195     */
196
197    public void changeData() {
198        if (getFirstName().equals(getLastName())) {
199            facesMessages.add(FacesMessage.SEVERITY_ERROR, "First name and last name must be different");
200        }
201
202        DocumentModel document = navigationContext.getCurrentDocument();
203        String title = getFirstName() + " " + getLastName();
204        document.setProperty("dublincore", "title", title);
205        document.setProperty("book", "rating", Long.valueOf(rating));
206        document.setProperty("book", "keywords", keywords);
207
208        documentManager.saveDocument(document);
209        documentManager.save();
210    }
211
212    public void validation(FacesContext context, UIComponent component, Object value) {
213        Integer v = (Integer) value;
214        if ((v.intValue() % 2) != 0) {
215            ((EditableValueHolder) component).setValid(false);
216            FacesMessage message = new FacesMessage();
217            message.setDetail("The value must be a multiple of 2");
218            message.setSummary("Not a multiple of 2");
219            message.setSeverity(FacesMessage.SEVERITY_ERROR);
220            facesMessages.add(component.getId(), message);
221        }
222    }
223
224    /*
225     * Search
226     */
227    public DocumentModelList getSearchResults() {
228        DocumentModelList result = documentManager.query("SELECT * FROM Book", 10);
229        return result;
230    }
231
232    /*
233     * Ajax
234     */
235
236    public boolean hasFilter() {
237        return filter != null;
238    }
239
240    public String getFilter() {
241        return filter;
242    }
243
244    public void setFilter(String newfilter) {
245        if (!(filter == null || filter.equals(newfilter))) {
246            // resultsProvidersCache.invalidate(BookResultsProviderFarm.KEYWORD_KEY);
247        }
248        this.filter = newfilter;
249    }
250
251    /*
252     * Seam remoting
253     */
254
255    /**
256     * @param param some string, that is directly passed from the Javascript code.
257     */
258    @WebRemote
259    public String something(String param) {
260        return "It worked: " + param;
261    }
262
263    /*
264     * Wizard
265     */
266    public String toWizardPage(String page) {
267        this.page = page;
268        return "bookwizard";
269    }
270
271    public String getWizardPage() {
272        return "/incl/bookwizard_page" + page + ".xhtml";
273    }
274
275    public String validateWizard() {
276        DocumentModel document = navigationContext.getChangeableDocument();
277        String title = getFirstName() + " " + getLastName();
278        document.setProperty("dublincore", "title", title);
279        document.setProperty("book", "isbn", isbn);
280        documentManager.saveDocument(document);
281        documentManager.save();
282        return webActions.setCurrentTabAndNavigate("TAB_VIEW");
283    }
284
285    /*
286     * Books listing in folder
287     */
288    public List<BookInfo> getBooksInFolder() {
289        List<BookInfo> list = new LinkedList<BookInfo>();
290
291        DocumentModel folder = navigationContext.getCurrentDocument();
292        DocumentModelList children = documentManager.getChildren(folder.getRef(), "Book");
293        for (DocumentModel doc : children) {
294            String[] keywords = (String[]) doc.getProperty("book", "keywords");
295            if (keywords == null) {
296                continue;
297            }
298            list.add(new BookInfo(doc, Arrays.asList(keywords)));
299        }
300        return list;
301    }
302
303    public static class BookInfo {
304
305        private DocumentModel doc;
306
307        private List<String> labels;
308
309        public BookInfo(DocumentModel doc, List<String> labels) {
310            this.doc = doc;
311            this.labels = labels;
312        }
313
314        public DocumentModel getDocument() {
315            return doc;
316        }
317
318        public List<String> getLabels() {
319            return labels;
320        }
321
322    }
323
324    /*
325     * Unused
326     */
327    public String duplicateSiblings() {
328        DocumentModel doc = navigationContext.getCurrentDocument();
329        DocumentModel folder = documentManager.getParentDocument(doc.getRef());
330        DocumentModel gp = documentManager.getParentDocument(folder.getRef());
331
332        // find the other folder names
333        Set<String> names = new HashSet<String>();
334        for (DocumentModel f : documentManager.getChildren(gp.getRef())) {
335            names.add(f.getName());
336        }
337        // find a new unique name
338        String newFolderName = folder.getName();
339        while (names.contains(newFolderName)) {
340            newFolderName += "copy";
341        }
342        // create the new folder
343        DocumentModel newFolder = documentManager.createDocumentModel(gp.getPathAsString(), newFolderName,
344                folder.getType());
345        newFolder.setProperty("dublincore", "title", "Nouveau folder");
346        documentManager.createDocument(newFolder);
347
348        // create the children
349        String newFolderPath = newFolder.getPathAsString();
350        for (DocumentModel child : documentManager.getChildren(folder.getRef(), "Book")) {
351            DocumentModel newChild = documentManager.createDocumentModel(newFolderPath, child.getName(), "Note");
352            String title = child.getProperty("dublincore", "title") + " duplicated";
353            newChild.setProperty("dublincore", "title", title);
354            documentManager.createDocument(newChild);
355        }
356        documentManager.save();
357
358        Events.instance().raiseEvent(EventNames.DOCUMENT_CHILDREN_CHANGED, gp);
359        return null;
360    }
361
362    public String getContainerPath() {
363        DocumentModel currentDocument = navigationContext.getCurrentDocument();
364        if (currentDocument.getDocumentType().getName().equals("Book"))
365            return currentDocument.getPath().removeLastSegments(1).toString();
366        return currentDocument.getPathAsString();
367    }
368
369}