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.io.File;
019import java.util.HashMap;
020import javax.jcr.Credentials;
021import javax.jcr.LoginException;
022import javax.jcr.Repository;
023import javax.jcr.RepositoryException;
024import javax.jcr.Session;
025import javax.jcr.Workspace;
026import javax.servlet.ServletContext;
027import org.modeshape.common.logging.Logger;
028import org.modeshape.jcr.JcrRepository;
029import org.modeshape.jcr.api.RepositoryManager;
030import org.modeshape.web.shared.RemoteException;
031import org.modeshape.web.server.LRepository;
032import org.modeshape.web.shared.BackupParams;
033import org.modeshape.web.shared.RestoreParams;
034
035/**
036 * @author kulikov
037 */
038public class LRepositoryImpl implements LRepository {
039    private Credentials creds;
040    private JcrRepository repository;
041    
042    //server's env
043    private transient ServletContext context;
044    private transient File tempDir;
045    
046    private HashMap<String, Session> sessions = new HashMap<>();
047    private String[] workspaces;
048    
049    private final static Logger logger = Logger.getLogger(LRepositoryImpl.class);
050
051    public LRepositoryImpl( ServletContext context, JcrRepository repository,
052                            Credentials creds ) throws LoginException, RepositoryException {
053        this.context = context;
054        this.creds = creds;
055        assert repository != null;
056        this.repository = repository;
057        
058        logger.debug("Logging to repository " + repository + " as " + creds);
059        
060        Session session = creds != null ? repository.login(creds) : repository.login();
061        sessions.put(session.getWorkspace().getName(), session);
062        
063        workspaces = session.getWorkspace().getAccessibleWorkspaceNames();
064        logger.debug("[" + this.repository.getName() + "] available workspaces " + wsnames());
065        
066        tempDir = (File) context.getAttribute("javax.servlet.context.tempdir");
067    }
068
069    @Override
070    public String name() {
071        return repository.getName();
072    }
073
074    @Override
075    public String[] getWorkspaces() {
076        logger.debug("[" + this.repository.getName() + "] Requested workspaces " + wsnames());
077        return workspaces;
078    }
079
080    private String wsnames() {
081        StringBuilder builder = new StringBuilder();
082        builder.append("{");
083        for (int i = 0; i < workspaces.length - 1; i++) {
084            builder.append(workspaces[i]);
085            builder.append(",");
086        }
087        builder.append(workspaces[workspaces.length - 1]);
088        builder.append("}");
089        return builder.toString();
090    }
091
092    @Override
093    public Session session( String workspace ) throws RemoteException {
094        if (sessions.containsKey(workspace)) {
095            logger.debug("[" + this.repository.getName() + "] has already session to " + workspace);
096            return sessions.get(workspace);
097        }
098
099        try {
100            logger.debug("[" + this.repository.getName() + "] has not yet session to " + workspace);
101            Session session = creds != null ? repository.login(creds, workspace) : repository.login(workspace);
102            sessions.put(workspace, session);
103            return session;
104        } catch (RepositoryException e) {
105            throw new RemoteException(e.getMessage());
106        }
107    }
108
109    private Session session() {
110        return sessions.values().iterator().next();
111    }
112
113    @Override
114    public Repository repository() {
115        return repository;
116    }
117
118    @Override
119    public void backup( String name, BackupParams options ) throws RemoteException {
120        try {
121            File dir = new File(tempDir.getAbsolutePath() + File.separator + name);
122            RepositoryManager mgr = ((org.modeshape.jcr.api.Session)session()).getWorkspace().getRepositoryManager();
123            mgr.backupRepository(dir, new BackupUsrOptions(options));
124        } catch (Exception e) {
125            throw new RemoteException(e.getMessage());
126        }
127    }
128
129    @Override
130    public void restore( String name, RestoreParams options ) throws RemoteException {
131        try {
132            File dir = new File(tempDir.getAbsolutePath() + File.separator + name);
133            RepositoryManager mgr = ((org.modeshape.jcr.api.Session)session()).getWorkspace().getRepositoryManager();
134            mgr.restoreRepository(dir, new RestoreUsrOptions(options));
135            
136            //after restore process session will be closed so we need to clean up
137            //sessions to avoid access of invalid session.
138            sessions.clear();
139        } catch (Exception e) {
140            throw new RemoteException(e.getMessage());
141        }
142    }
143
144    public void importXML( String workspace ) throws RemoteException {
145        try {
146            Workspace ws = ((org.modeshape.jcr.api.Session)session(workspace)).getWorkspace();
147            ws.importXML(workspace, null, 0);
148        } catch (Exception e) {
149            throw new RemoteException(e.getMessage());
150        }
151    }
152
153}