001/**
002 * Copyright 2011 The Kuali Foundation Licensed under the
003 * Educational Community License, Version 2.0 (the "License"); you may
004 * not use this file except in compliance with the License. You may
005 * obtain a copy of the License at
006 *
007 * http://www.osedu.org/licenses/ECL-2.0
008 *
009 * Unless required by applicable law or agreed to in writing,
010 * software distributed under the License is distributed on an "AS IS"
011 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
012 * or implied. See the License for the specific language governing
013 * permissions and limitations under the License.
014 */
015
016package org.kuali.mobility.database.controllers;
017
018import org.apache.commons.io.IOUtils;
019import org.kuali.mobility.database.entity.DatabaseSchemaOutputForm;
020import org.kuali.mobility.database.service.DatabaseService;
021import org.kuali.mobility.database.validators.DatabaseSchemaOutputFormValidator;
022import org.kuali.mobility.security.authn.util.AuthenticationConstants;
023import org.kuali.mobility.security.group.api.Group;
024import org.kuali.mobility.security.user.api.User;
025import org.springframework.beans.factory.annotation.Autowired;
026import org.springframework.stereotype.Controller;
027import org.springframework.ui.Model;
028import org.springframework.validation.BindingResult;
029import org.springframework.web.bind.annotation.ModelAttribute;
030import org.springframework.web.bind.annotation.RequestMapping;
031import org.springframework.web.bind.annotation.RequestMethod;
032
033import javax.servlet.http.HttpServletRequest;
034import javax.servlet.http.HttpServletResponse;
035import java.io.ByteArrayInputStream;
036import java.io.IOException;
037import java.io.InputStream;
038import java.util.LinkedHashMap;
039import java.util.Map;
040import org.slf4j.Logger;
041import org.slf4j.LoggerFactory;
042
043@Controller 
044@RequestMapping("/database")
045public class DatabaseController {
046
047        private static Logger LOG = LoggerFactory.getLogger(DatabaseController.class);
048        
049    @Autowired
050    private DatabaseService service;
051    public void setDatabaseService(DatabaseService service) {
052        this.service = service;
053    }
054        
055    private static final Map<String, String> dialectTypes;
056    
057    static {
058        dialectTypes = new LinkedHashMap<String, String>();
059        dialectTypes.put("", "Select a Database Type");
060        dialectTypes.put("org.hibernate.dialect.Oracle10gDialect", "Oracle10g");
061//      dialectTypes.put("org.kuali.mobility.database.entity.KMEOracleDialect", "Oracle");
062        dialectTypes.put("org.hibernate.dialect.MySQL5Dialect", "MySQL5");
063//      dialectTypes.put("org.kuali.mobility.database.entity.KMEMySql5Dialect", "MySQL5");
064        dialectTypes.put("org.hibernate.dialect.SQLServerDialect", "SQL Server");
065        dialectTypes.put("org.hibernate.dialect.PostgreSQLDialect", "PostgreSQL");
066        dialectTypes.put("org.hibernate.dialect.DerbyDialect", "Derby");
067            dialectTypes.put("org.hibernate.dialect.H2Dialect","H2");
068//      dialectTypes.put("", "");
069    }
070    
071    @RequestMapping(method = RequestMethod.GET)
072    public String index(Model uiModel, HttpServletRequest request) {
073//      String schema = service.getSchema();
074//      uiModel.addAttribute("schema", schema);
075        String viewName;
076        if (!isAllowedAccess("KME-ADMINISTRATORS", request)) {
077                viewName = "redirect:/errors/401.jsp";
078            LOG.info("Redirecting to: " + viewName );
079            return viewName;
080        } else {
081                DatabaseSchemaOutputForm form = new DatabaseSchemaOutputForm();
082                uiModel.addAttribute("form", form);
083                        uiModel.addAttribute("dialectTypes", dialectTypes);
084                return "database/schemaoutputform";
085        }
086    }
087    
088    @RequestMapping(method = RequestMethod.POST)
089    public String getSchema(HttpServletRequest request, Model uiModel, @ModelAttribute("form") DatabaseSchemaOutputForm form, BindingResult result) {
090        
091        String viewName;
092        if (!isAllowedAccess("KME-ADMINISTRATORS", request)) {
093                viewName = "redirect:/errors/401.jsp";
094            LOG.info("Redirecting to: " + viewName );
095            return viewName;
096        }
097        
098        DatabaseSchemaOutputFormValidator validator = new DatabaseSchemaOutputFormValidator();
099                validator.validate(form, result);
100        
101        if (result.hasErrors()) {
102                        uiModel.addAttribute("dialectTypes", dialectTypes);
103                        return "database/schemaoutputform";
104                } else {
105                String schema = this.getSchema(form.getDialectType(), form.getDelimiter(), form.isNewLineBeforeDelimiter(), form.isRemoveForeignKeys());
106                uiModel.addAttribute("schema", schema);
107                uiModel.addAttribute("dialect", form.getDialectType());
108                uiModel.addAttribute("delimiter", form.getDelimiter());
109                        return "database/schemaoutput";
110                }
111    }
112
113    @RequestMapping(method = RequestMethod.POST, params = "download")
114    public String getSchemaDownload(HttpServletRequest request, Model uiModel, @ModelAttribute("form") DatabaseSchemaOutputForm form, BindingResult result, HttpServletResponse response) {
115        String viewName;
116        if (!isAllowedAccess("KME-ADMINISTRATORS", request)) {
117                viewName = "redirect:/errors/401.jsp";
118            LOG.info("Redirecting to: " + viewName );
119            return viewName;
120        } 
121        
122        DatabaseSchemaOutputFormValidator validator = new DatabaseSchemaOutputFormValidator();
123                validator.validate(form, result);
124
125                if (result.hasErrors()) {
126                        uiModel.addAttribute("dialectTypes", dialectTypes);
127                        return "database/schemaoutputform";
128                } else {
129                        try {
130                                response.setContentType("text/plain");
131                                response.setHeader("Content-Disposition", "attachment;filename=schema.ddl");
132                                String schema = this.getSchema(form.getDialectType(), form.getDelimiter(), form.isNewLineBeforeDelimiter(), form.isRemoveForeignKeys());
133                                InputStream is = new ByteArrayInputStream(schema.getBytes("UTF-8"));
134                                IOUtils.copy(is, response.getOutputStream());
135                                response.flushBuffer();
136                        } catch (IOException ex) {
137                                // log.info("Error writing file to output stream. Filename was '" +
138                                // fileName + "'");
139                                throw new RuntimeException("IOError writing file to output stream");
140                        }
141                        return null;
142                }
143    }
144
145    /*
146    @RequestMapping(value="/schema", method = RequestMethod.GET)
147        @ResponseBody
148        public String getSchema(@RequestParam(value = "dialect", required = true) String dialect, @RequestParam(value = "delimiter", required = true) String delimiter, HttpServletRequest request) {
149//              User user = (User) request.getSession().getAttribute(Constants.KME_USER_KEY);
150                String schema = service.getSchema(dialect, delimiter);
151                return schema;
152        }
153        */
154    
155    /*
156    @RequestMapping(value = "/schema2", method = RequestMethod.GET)
157    public void getFile(@RequestParam(value = "dialect", required = true) String dialect, @RequestParam(value = "delimiter", required = true) String delimiter, @RequestParam(value = "newline", required = true) boolean newLine, HttpServletResponse response) {
158                try {
159                        response.setContentType("text/plain");
160                        response.setHeader("Content-Disposition", "attachment;filename=schema.ddl");
161                        String schema = this.getSchema(dialect, delimiter, newLine);
162                        InputStream is = new ByteArrayInputStream(schema.getBytes("UTF-8"));
163                        IOUtils.copy(is, response.getOutputStream());
164                        response.flushBuffer();
165                } catch (IOException ex) {
166                        // log.info("Error writing file to output stream. Filename was '" +
167                        // fileName + "'");
168                        throw new RuntimeException("IOError writing file to output stream");
169                }
170    }
171    */
172    
173    private String getSchema(String dialect, String delimiter, boolean newLine, boolean overrideAlterTable) {
174                if (newLine) {
175                        delimiter = "\n" + delimiter;
176                }
177                String schema = service.getSchema(dialect, delimiter, overrideAlterTable);
178                return schema;
179    }
180    
181    public boolean isAllowedAccess(String roleName, HttpServletRequest request) {
182        boolean isAllowed = false;
183
184        if( roleName == null || roleName.isEmpty() ) {
185            isAllowed = true;
186        } else if ( request.getSession() == null ) {
187                LOG.info("Request Session NULL");
188                isAllowed = false;
189        } else {
190            User user = (User)request.getSession().getAttribute(AuthenticationConstants.KME_USER_KEY);
191            if( user == null || user.isPublicUser() ) {
192                LOG.info("User NULL or Public");                
193                isAllowed = false;
194            } else if( user.getGroups() == null || user.getGroups().isEmpty() ) {
195                LOG.info("UserGrous NULL or isEmpty()");
196                isAllowed = false;
197            } else {
198                for( Group group : user.getGroups() ) {
199                        LOG.info(group.getName());
200                    if( group.getName().equalsIgnoreCase(roleName) ) {
201                        isAllowed = true;
202                        break;
203                    }
204                }
205            }
206        }
207//        return true;
208        return isAllowed;
209    }
210
211    
212}