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.relations.impl;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import javax.jcr.ItemNotFoundException;
23  import javax.jcr.Node;
24  import javax.jcr.Property;
25  import javax.jcr.Session;
26  import javax.jcr.Value;
27  
28  import org.exoplatform.container.xml.InitParams;
29  import org.exoplatform.services.cms.relations.RelationsService;
30  import org.exoplatform.services.jcr.RepositoryService;
31  import org.exoplatform.services.jcr.core.ManageableRepository;
32  import org.exoplatform.services.jcr.ext.common.SessionProvider;
33  import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
34  import org.exoplatform.services.log.ExoLogger;
35  import org.exoplatform.services.log.Log;
36  import org.picocontainer.Startable;
37  
38  /**
39   * @author monica franceschini
40   */
41  
42  public class RelationsServiceImpl implements RelationsService, Startable {
43    private static final String RELATION_MIXIN = "exo:relationable";
44    private static final String RELATION_PROP = "exo:relation";
45  
46    private RepositoryService repositoryService_;
47    private static final Log LOG  = ExoLogger.getLogger(RelationsServiceImpl.class.getName());
48    public RelationsServiceImpl(RepositoryService repositoryService,
49        NodeHierarchyCreator nodeHierarchyCreator, InitParams params) {
50      repositoryService_ = repositoryService;
51    }
52  
53    /**
54     * {@inheritDoc}
55     */
56    public boolean hasRelations(Node node) throws Exception {
57      if (node.isNodeType(RELATION_MIXIN)) return true;
58      return false;
59  
60    }
61  
62    /**
63     * Get node by UUID
64     * @param uuid          The specified UUI.
65     * @param repository    The name of repository
66     * @param provider      SessionProvider
67     * @see                 SessionProvider
68     * @return              Node with specified UUID
69     * @throws Exception
70     */
71    private Node getNodeByUUID(String uuid, SessionProvider provider) throws Exception {
72      ManageableRepository manageRepo = repositoryService_.getCurrentRepository();
73      String[] workspaces = manageRepo.getWorkspaceNames() ;
74      for(String ws : workspaces) {
75        try{
76          return provider.getSession(ws,manageRepo).getNodeByUUID(uuid) ;
77        } catch(Exception e) {
78          continue ;
79        }
80      }
81      return null;
82    }
83  
84    /**
85     * {@inheritDoc}
86     */
87    public List<Node> getRelations(Node node, SessionProvider provider) {
88      List<Node> rels = new ArrayList<Node>();
89      try {
90        if(node.hasProperty(RELATION_PROP)) {
91          Value[] values = node.getProperty(RELATION_PROP).getValues();
92          for (int i = 0; i < values.length; i++) {
93            if(getNodeByUUID(values[i].getString(), provider) != null) {
94              rels.add(getNodeByUUID(values[i].getString(), provider));
95            }
96          }
97        }
98      } catch(Exception e) {
99        if (LOG.isWarnEnabled()) {
100         LOG.warn(e.getMessage());
101       }
102     }
103     return rels ;
104   }  
105 
106   /**
107    * {@inheritDoc}
108    */
109   public void removeRelation(Node node, String relationPath) throws Exception {
110     List<Value> vals = new ArrayList<Value>();
111     if (!"*".equals(relationPath) && node.hasProperty(RELATION_PROP)) {
112       SessionProvider provider = SessionProvider.createSystemProvider() ;
113       Property relations = node.getProperty(RELATION_PROP);
114       if (relations != null) {
115         Value[] values = relations.getValues();
116         String uuid2Remove = null;
117         for (int i = 0; i < values.length; i++) {
118           String uuid = values[i].getString();
119           Node refNode = getNodeByUUID(uuid, provider);
120           if(refNode == null) continue ;
121           if (refNode.getPath().equals(relationPath)) uuid2Remove = uuid;
122           else vals.add(values[i]);
123         }
124         if (uuid2Remove == null) return;
125       }
126       provider.close();
127       if(vals.size() == 0) node.removeMixin(RELATION_MIXIN);
128       else node.setProperty(RELATION_PROP, vals.toArray(new Value[vals.size()]));
129       node.save() ;
130     }
131   }  
132 
133   /**
134    * {@inheritDoc}
135    */
136   public void addRelation(Node node, String relationPath,String workspace) throws Exception {
137     SessionProvider provider = SessionProvider.createSystemProvider() ;
138     Session session = getSession(workspace,provider) ;
139     Node catNode = (Node) session.getItem(relationPath);
140     if(!catNode.isNodeType("mix:referenceable")) {
141       catNode.addMixin("mix:referenceable") ;
142       catNode.save() ;
143       session.save() ;
144     }
145     Value value2add = session.getValueFactory().createValue(catNode);
146     if (!node.isNodeType(RELATION_MIXIN)) {
147       node.addMixin(RELATION_MIXIN);
148       node.setProperty(RELATION_PROP, new Value[] {value2add});
149       node.save() ;
150       session.save() ;
151     } else {
152       List<Value> vals = new ArrayList<Value>();
153       Value[] values = node.getProperty(RELATION_PROP).getValues();
154       for (int i = 0; i < values.length; i++) {
155         Value value = values[i];
156         String uuid = value.getString();
157         Node refNode = null ;
158         try {
159           refNode = getNodeByUUID(uuid, provider) ;
160         } catch(ItemNotFoundException ie) {
161           removeRelation(node, relationPath) ;
162           continue ;
163         }
164         if(refNode.getPath().equals(relationPath)) return;
165         vals.add(value);
166       }
167       vals.add(value2add);
168       node.setProperty(RELATION_PROP, vals.toArray(new Value[vals.size()]));
169       node.save() ;
170       session.save() ;
171       session.logout();
172       provider.close();
173     }
174   }  
175 
176   /**
177    * {@inheritDoc}
178    */
179   public void start() {
180   }
181 
182   /**
183    * {@inheritDoc}
184    */
185   public void stop() {
186   }
187   
188   /**
189    * {@inheritDoc}
190    */
191   public void init() throws Exception {
192   }
193 
194   /**
195    * Get session of respository
196    * @see                 Session
197    * @return              Session
198    * @throws Exception
199    */
200   protected Session getSession() throws Exception {
201     ManageableRepository manageableRepository = repositoryService_.getCurrentRepository();
202     String workspaceName = manageableRepository.getConfiguration().getSystemWorkspaceName();
203     return manageableRepository.getSystemSession(workspaceName);
204   }
205 
206   /**
207    * Get session of workspace
208    * @param workspace     The name of workspace
209    * @param provider      SessionProvider
210    * @see                 SessionProvider
211    * @return              Session
212    * @throws Exception
213    */
214   private Session getSession(String workspace, SessionProvider provider) throws Exception {
215     ManageableRepository manageableRepository = repositoryService_.getCurrentRepository();
216     return provider.getSession(workspace, manageableRepository);
217   }
218 }