001/*
002 * ModeShape (http://www.modeshape.org)
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 */
016package org.modeshape.web.server.impl;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.HashMap;
021import javax.jcr.Credentials;
022import javax.jcr.SimpleCredentials;
023import javax.naming.InitialContext;
024import javax.naming.NamingException;
025import javax.servlet.ServletContext;
026import org.modeshape.common.logging.Logger;
027import org.modeshape.jcr.ModeShapeEngine;
028import org.modeshape.web.shared.RemoteException;
029import org.modeshape.web.server.Connector;
030import org.modeshape.web.server.LRepository;
031import org.modeshape.web.shared.RepositoryName;
032
033/**
034 *
035 * @author kulikov
036 */
037public class ConnectorImpl implements Connector {
038    private final static String JNDI_PREFIX_PARAM = "jndi-prefix";
039    private final static String DEFAULT_JNDI_PREFIX = "jcr";
040    
041    //this object will be serialized by user session but 
042    //we do not want to serialize any data so mark everything as transient
043    private static final long serialVersionUID = 1L;
044    
045    private transient HashMap<String, LRepository> repositories = new HashMap<>();
046    
047    //names of the available repositories
048    private transient Collection<RepositoryName> repositoryNames;
049    
050    //user's credentials
051    private transient Credentials credentials;
052    private transient String userName;
053    
054    private transient ModeShapeEngine engine;
055    private transient RepositoryList repoList;
056    
057    //reference to the server's env
058    private transient ServletContext context;
059    
060    private final static Logger logger = Logger.getLogger(ConnectorImpl.class);
061    
062    public ConnectorImpl() {
063    }
064    
065    @Override
066    public void start(ServletContext context) throws RemoteException {
067        this.context = context;
068        
069        String jndiPrefix = context.getInitParameter(JNDI_PREFIX_PARAM);
070        if (jndiPrefix == null) jndiPrefix = DEFAULT_JNDI_PREFIX;
071        try {
072            InitialContext ic = new InitialContext();
073            engine = (ModeShapeEngine) ic.lookup(jndiPrefix);            
074            repoList = new RepositoryList(engine);
075            repositoryNames = repoList.getRepositories(null);
076        } catch (NamingException | RemoteException e) {
077            throw new RemoteException(e.getMessage());
078        }
079    }
080    
081    @Override
082    public void login( String username, String password ) throws RemoteException {        
083        this.userName = username;
084        if (username == null) {
085            credentials = null;
086        }
087        
088        if (password == null) {
089            credentials = new SimpleCredentials(username, null);
090        } else {
091            credentials = new SimpleCredentials(username, password.toCharArray());
092        }
093        
094        try {
095            repositoryNames = repoList.getRepositories(credentials);
096        } catch (Exception e) {
097            throw new RemoteException(e.getMessage());
098        }
099    }
100
101    @Override
102    public void logout() {
103        credentials = null;
104        userName = null;
105        try {
106            repositoryNames = repoList.getRepositories(null);
107        } catch (RemoteException e) {
108            repositoryNames.clear();
109        }
110    }
111    
112    @Override
113    public String userName() {
114        return userName;
115    }
116    
117    @Override
118    public Collection<RepositoryName> getRepositories() {
119        return repositoryNames;
120    }
121
122    @Override
123    public LRepository find(String name) throws RemoteException {
124        if (!repositories.containsKey(name)) {
125            try {
126                logger.debug("Starting repository: " + name);
127                repositories.put(name, 
128                        new LRepositoryImpl(context, 
129                        engine.getRepository(name), credentials));
130            } catch (Exception e) {
131                logger.debug("Could not start repository " + name, e);
132                throw new RemoteException(e.getMessage());
133            }
134        }
135        return repositories.get(name);
136    }
137
138    @Override
139    public Collection<RepositoryName> search(String name) {
140        ArrayList<RepositoryName> list = new ArrayList<>();
141        for (RepositoryName n : repositoryNames) {
142            if (n.getName().contains(name) || n.getDescriptor().contains(name)) {
143                list.add(n);
144            }
145        }
146        return list;
147    }
148    
149    
150}