View Javadoc
1   /*
2    * Copyright (C) 2003-2007 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.services.cms.metadata.impl;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.InputStream;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import javax.jcr.Node;
25  import javax.jcr.PathNotFoundException;
26  import javax.jcr.Session;
27  import javax.jcr.nodetype.NodeType;
28  import javax.jcr.nodetype.NodeTypeIterator;
29  import javax.jcr.nodetype.PropertyDefinition;
30  
31  import org.exoplatform.container.component.ComponentPlugin;
32  import org.exoplatform.services.cms.BasePath;
33  import org.exoplatform.services.cms.impl.DMSConfiguration;
34  import org.exoplatform.services.cms.impl.DMSRepositoryConfiguration;
35  import org.exoplatform.services.cms.metadata.MetadataService;
36  import org.exoplatform.services.cms.templates.TemplateService;
37  import org.exoplatform.services.cms.templates.impl.TemplatePlugin;
38  import org.exoplatform.services.jcr.RepositoryService;
39  import org.exoplatform.services.jcr.core.nodetype.ExtendedNodeTypeManager;
40  import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
41  import org.exoplatform.services.log.ExoLogger;
42  import org.exoplatform.services.log.Log;
43  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
44  import org.picocontainer.Startable;
45  
46  /**
47   * Process with meta data for system
48   */
49  public class MetadataServiceImpl implements MetadataService, Startable{
50  
51    /**
52     * NodeType NT_UNSTRUCTURED
53     */
54    final static public String NT_UNSTRUCTURED = "nt:unstructured";
55  
56    /**
57     * Property name INTERNAL_USE
58     */
59    final static public String INTERNAL_USE = "exo:internalUse";
60  
61    /**
62     * NodeType METADATA_TYPE
63     */
64    final static public String METADATA_TYPE = "exo:metadata";
65  
66    /**
67     * Node name DIALOGS
68     */
69    final static public String DIALOGS = "dialogs";
70  
71    /**
72     * Node name VIEWS
73     */
74    final static public String VIEWS = "views";
75  
76    /**
77     * Node name DIALOG1
78     */
79    final static public String DIALOG1 = "dialog1";
80  
81    /**
82     * Node name VIEW1
83     */
84    final static public String VIEW1 = "view1";
85  
86    /**
87     * RepositoryService object process with repository
88     */
89    private RepositoryService repositoryService_;
90  
91    /**
92     * NodeHierarchyCreator object
93     */
94    private NodeHierarchyCreator nodeHierarchyCreator_;
95  
96    /**
97     * Path to Metadata node in System workspace
98     */
99    private String baseMetadataPath_;
100 
101   /**
102    * List of TemplatePlugin plugins_
103    */
104   private List<TemplatePlugin> plugins_ = new ArrayList<TemplatePlugin>();
105 
106   /**
107   * DMS configuration which used to store informations
108   */
109   private DMSConfiguration dmsConfiguration_;
110   private static final Log LOG  = ExoLogger.getLogger(MetadataServiceImpl.class.getName());
111 
112   private TemplateService templateService;
113 
114   /**
115    * Constructor method
116    * @param nodeHierarchyCreator  NodeHierarchyCreator object
117    * @param repositoryService     RepositoryService object
118    * @param dmsConfiguration DMSConfiguration object
119    * @throws Exception
120    */
121   public MetadataServiceImpl(NodeHierarchyCreator nodeHierarchyCreator,
122       RepositoryService repositoryService, DMSConfiguration dmsConfiguration) throws Exception {
123     nodeHierarchyCreator_ = nodeHierarchyCreator;
124     repositoryService_ = repositoryService;
125     baseMetadataPath_ = nodeHierarchyCreator_.getJcrPath(BasePath.METADATA_PATH);
126     dmsConfiguration_ = dmsConfiguration;
127     templateService = WCMCoreUtils.getService(TemplateService.class);
128   }
129 
130   /**
131    * {@inheritDoc}
132    */
133   public void start() {
134     try {
135       init();
136     } catch (Exception e) {
137       if (LOG.isErrorEnabled()) {
138         LOG.error("Unexpected error", e);
139       }
140     }
141   }
142 
143   /**
144    * {@inheritDoc}
145    */
146   public void stop() {}
147 
148   /**
149    * Add TemplatePlugin
150    * @param plugin
151    */
152   public void addPlugins(ComponentPlugin plugin) {
153     if (plugin instanceof TemplatePlugin) plugins_.add((TemplatePlugin) plugin);
154   }
155 
156   /**
157    * Call all available in list of TemplatePlugin to
158    * add some predefine template to all repository got
159    * from configuration
160    * @throws Exception
161    */
162   public void init() throws Exception{
163     for(TemplatePlugin plugin : plugins_) {
164       try {
165         plugin.setBasePath(baseMetadataPath_);
166         plugin.init();
167       } catch(Exception e) {
168         if (LOG.isErrorEnabled()) {
169           LOG.error("Unexpected error", e);
170         }
171       }
172     }
173   }
174  
175   /**
176    * {@inheritDoc}
177    */
178   public String addMetadata(String nodetype,
179                             boolean isDialog,
180                             String role,
181                             String content,
182                             boolean isAddNew) throws Exception {
183     return addMetadata(nodetype, isDialog, role, content, nodetype, isAddNew);
184   } 
185   
186   /**
187    * {@inheritDoc}
188    */
189   public String addMetadata(String nodetype,
190                             boolean isDialog,
191                             String role,
192                             String content,
193                             String label,
194                             boolean isAddNew) throws Exception {
195     Session session = getSession();
196     Node metadataHome = (Node)session.getItem(baseMetadataPath_);
197     String path = null;
198     if(!isAddNew) {
199       if(isDialog) {
200         Node dialog1 = metadataHome.getNode(nodetype).getNode(DIALOGS).getNode(DIALOG1);
201         path = templateService.updateTemplate(dialog1, new ByteArrayInputStream(content.getBytes()), role.split(";"));
202         metadataHome.getNode(nodetype).setProperty("label", label);
203         metadataHome.save();
204       } else {
205         Node view1 = metadataHome.getNode(nodetype).getNode(VIEWS).getNode(VIEW1);
206         path = templateService.updateTemplate(view1, new ByteArrayInputStream(content.getBytes()), role.split(";"));
207         metadataHome.getNode(nodetype).setProperty("label", label);
208         metadataHome.save();
209       }
210       return path;
211     } 
212     Node metadata = null;
213     if(metadataHome.hasNode(nodetype)) metadata = metadataHome.getNode(nodetype);
214     else metadata = metadataHome.addNode(nodetype, NT_UNSTRUCTURED);
215     metadata.setProperty("label", label);
216     metadataHome.save();
217     addTemplate(metadata, role, new ByteArrayInputStream(content.getBytes()), isDialog);
218     metadataHome.save();
219     return metadata.getPath();
220   }    
221 
222   /**
223    * Add new node named nodetype
224    * And child node for dialog template node or view template node
225    * Set property EXO_ROLES_PROP, EXO_TEMPLATE_FILE_PROP for child node
226    * @param nodetype    Node name for processing
227    * @param isDialog    true for dialog template
228    * @param role        permission
229    * @param content     content of template
230    * @throws Exception
231    */
232   private void addTemplate(Node nodetype, String role, InputStream content, boolean isDialog) throws Exception {
233     Node templateHome = createTemplateHome(nodetype, isDialog);
234     String[] arrRoles = {};
235     if(role != null) arrRoles = role.split(";");
236     if(isDialog) {
237       templateService.createTemplate(templateHome, DIALOG1, DIALOG1, content, arrRoles);
238     } else {
239       templateService.createTemplate(templateHome, VIEW1, VIEW1, content, arrRoles);
240     }
241   }
242 
243   /**
244    * {@inheritDoc}
245    */
246   public void removeMetadata(String nodetype) throws Exception {
247     Session session = getSession();
248     Node metadataHome = (Node)session.getItem(baseMetadataPath_);
249     Node metadata = metadataHome.getNode(nodetype);
250     metadata.remove();
251     metadataHome.save();
252   }  
253   
254   /**
255    * {@inheritDoc}
256    */
257   public List<String> getMetadataList() throws Exception {
258     List<String> metadataTypes = new ArrayList<String>();
259     for(NodeType metadata:getAllMetadatasNodeType()) {
260       metadataTypes.add(metadata.getName());
261     }
262     return metadataTypes;
263   }
264   
265   /**
266    * {@inheritDoc}
267    */
268   public List<NodeType> getAllMetadatasNodeType() throws Exception {
269     List<NodeType> metadataTypes = new ArrayList<NodeType>();
270     ExtendedNodeTypeManager ntManager = repositoryService_.getCurrentRepository().getNodeTypeManager();
271     NodeTypeIterator ntIter = ntManager.getMixinNodeTypes();
272     while(ntIter.hasNext()) {
273       NodeType nt = ntIter.nextNodeType();
274       if(nt.isNodeType(METADATA_TYPE) && !nt.getName().equals(METADATA_TYPE)) metadataTypes.add(nt);
275     }
276     return metadataTypes;
277   }  
278 
279 
280   /**
281    * Create node for Dialog template or view template
282    * @param nodetype    Node name for processing
283    * @param isDialog    true for dialog template, false for view template
284    * @return            Node for dialog template if isDialog = true
285    *                    Node for dialog template if isDialog = false
286    * @throws Exception
287    */
288   private Node createTemplateHome(Node nodetype, boolean isDialog) throws Exception{
289     if(isDialog) {
290       Node dialogs = null;
291       if(nodetype.hasNode(DIALOGS)) dialogs = nodetype.getNode(DIALOGS);
292       else dialogs = nodetype.addNode(DIALOGS, NT_UNSTRUCTURED);
293       return dialogs;
294     }
295     Node views = null;
296     if(nodetype.hasNode(VIEWS)) views = nodetype.getNode(VIEWS);
297     else views = nodetype.addNode(VIEWS, NT_UNSTRUCTURED);
298     return views;
299   }
300 
301   /**
302    * {@inheritDoc}
303    */
304   public String getMetadataTemplate(String name, boolean isDialog) throws Exception {
305     Session session = getSession();
306     Node metadataHome = (Node)session.getItem(baseMetadataPath_);
307     Node template = null;
308     if(!hasMetadata(name)) return null;
309     if(isDialog) template = metadataHome.getNode(name).getNode(DIALOGS).getNode(DIALOG1);
310     else template = metadataHome.getNode(name).getNode(VIEWS).getNode(VIEW1);
311     String ret = templateService.getTemplate(template);
312     return ret;
313   }  
314 
315   /**
316    * {@inheritDoc}
317    */
318   public String getMetadataPath(String name, boolean isDialog) throws Exception {
319     Session session = getSession();
320     Node metadataHome = (Node)session.getItem(baseMetadataPath_);
321     if(!hasMetadata(name)) return null;
322     Node template = null;
323     if(isDialog){
324       template = metadataHome.getNode(name).getNode(DIALOGS).getNode(DIALOG1);
325     } else {
326       template = metadataHome.getNode(name).getNode(VIEWS).getNode(VIEW1);
327     }
328     String ret = template.getPath();
329     return ret;
330   }  
331 
332   /**
333    * {@inheritDoc}
334    */
335   public String getMetadataRoles(String name, boolean isDialog) throws Exception {
336     Session session = getSession();
337     Node metadataHome = (Node)session.getItem(baseMetadataPath_);
338     Node template = null;
339     if(!hasMetadata(name)) return null;
340     if(isDialog){
341       template = metadataHome.getNode(name).getNode(DIALOGS).getNode(DIALOG1);
342     } else {
343       template = metadataHome.getNode(name).getNode(VIEWS).getNode(VIEW1);
344     }
345     String ret = templateService.getTemplateRoles(template);
346     return ret;
347   }  
348   
349   /**
350    * {@inheritDoc}
351    */
352   public boolean hasMetadata(String name) throws Exception {
353     Session session = getSession();
354     Node metadataHome = (Node)session.getItem(baseMetadataPath_);
355     if(metadataHome.hasNode(name)) {
356       return true;
357     }
358     return false;
359   }  
360   
361   /**
362    * {@inheritDoc}
363    */
364   public List<String> getExternalMetadataType() throws Exception {
365     List<String> extenalMetaTypes = new ArrayList<String>();
366     for (NodeType metadata : getAllMetadatasNodeType()) {
367       for (PropertyDefinition pro : metadata.getPropertyDefinitions()) {
368         if (pro.getName().equals(INTERNAL_USE)) {
369           if (!pro.getDefaultValues()[0].getBoolean() && !metadata.getName().equals(METADATA_TYPE))
370             extenalMetaTypes.add(metadata.getName());
371           break;
372         }
373       }
374     }
375 
376     return extenalMetaTypes;
377   }
378   
379 
380   @Override
381   /**
382    * {@inheritDoc}
383    */
384   public Node getMetadata(String metaName) throws Exception {
385     Node metadataHome = (Node)getSession().getItem(baseMetadataPath_);
386     try {
387       return metadataHome.getNode(metaName);
388     } catch(PathNotFoundException pne) {
389       return null;
390     } 
391   }
392 
393   @Override
394   /**
395    * {@inheritDoc}
396    */
397   public String getMetadataLabel(String metaName) throws Exception {
398     if(getMetadata(metaName) != null) {
399       try {
400         return getMetadata(metaName).getProperty("label").getString();
401       } catch(PathNotFoundException pne) {
402         return metaName;
403       }
404     }
405     return null;
406   }
407   
408   private Session getSession() throws Exception{
409     DMSRepositoryConfiguration dmsRepoConfig = dmsConfiguration_.getConfig();
410     return WCMCoreUtils.getSystemSessionProvider().getSession(dmsRepoConfig.getSystemWorkspace(), 
411             repositoryService_.getCurrentRepository());
412   }
413 
414 }