Java tutorial
/** * Axelor Business Solutions * * Copyright (C) 2015 Axelor (<http://axelor.com>). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.axelor.auth.service; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import org.apache.commons.io.output.FileWriterWithEncoding; import org.joda.time.LocalDateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import au.com.bytecode.opencsv.CSVReader; import au.com.bytecode.opencsv.CSVWriter; import com.axelor.app.AppSettings; import com.axelor.auth.db.Group; import com.axelor.auth.db.IMessage; import com.axelor.auth.db.Permission; import com.axelor.auth.db.PermissionAssistant; import com.axelor.auth.db.repo.GroupRepository; import com.axelor.auth.db.repo.PermissionAssistantRepository; import com.axelor.auth.db.repo.PermissionRepository; import com.axelor.i18n.I18n; import com.axelor.inject.Beans; import com.axelor.meta.MetaFiles; import com.axelor.meta.db.MetaField; import com.axelor.meta.db.MetaFile; import com.axelor.meta.db.MetaModel; import com.axelor.meta.db.MetaPermission; import com.axelor.meta.db.MetaPermissionRule; import com.axelor.meta.db.repo.MetaModelRepository; import com.axelor.meta.db.repo.MetaPermissionRepository; import com.axelor.meta.db.repo.MetaPermissionRuleRepository; import com.google.common.base.Strings; import com.google.inject.Inject; import com.google.inject.persist.Transactional; public class PermissionAssistantService { private static final Logger LOG = LoggerFactory.getLogger(PermissionAssistantService.class); @Inject private MetaPermissionRepository metaPermissionRepository; @Inject private PermissionRepository permissionRepository; @Inject private MetaPermissionRuleRepository ruleRepository; @Inject private GroupRepository groupRepository; @Inject private MetaModelRepository modelRepository; private String errorLog = ""; @SuppressWarnings("serial") private List<String> groupHeader = new ArrayList<String>() { { add(""); add(I18n.get("Read")); add(I18n.get("Write")); add(I18n.get("Create")); add(I18n.get("Delete")); add(I18n.get("Export")); add(I18n.get("Readonly If")); add(I18n.get("Hide If")); } }; private String getFileName(PermissionAssistant assistant) { String userCode = assistant.getCreatedBy().getCode(); String dateString = LocalDateTime.now().toString("yyyyMMddHHmm"); String fileName = userCode + "-" + dateString + ".csv"; return fileName; } public void createFile(PermissionAssistant assistant) { AppSettings appSettings = AppSettings.get(); File permFile = new File(appSettings.get("file.upload.dir"), getFileName(assistant)); try { FileWriterWithEncoding fileWriter = new FileWriterWithEncoding(permFile, "utf-8"); CSVWriter csvWriter = new CSVWriter(fileWriter, ';'); writeGroup(csvWriter, assistant); csvWriter.close(); createMetaFile(permFile, assistant); } catch (Exception e) { e.printStackTrace(); } } @Transactional public void createMetaFile(File permFile, PermissionAssistant assistant) { MetaFile metaFile = new MetaFile(); metaFile.setFileName(permFile.getName()); metaFile.setFilePath(permFile.getName()); assistant.setMetaFile(metaFile); Beans.get(PermissionAssistantRepository.class).save(assistant); } private void writeGroup(CSVWriter csvWriter, PermissionAssistant assistant) { @SuppressWarnings("serial") List<String> headerRow = new ArrayList<String>() { { add("Object"); add("Field"); add("Title"); } }; String[] groupRow = new String[assistant.getGroupSet().size() * 8 + 3]; Integer count = 3; for (Group group : assistant.getGroupSet()) { groupRow[count + 1] = group.getCode(); headerRow.addAll(groupHeader); count += 8; } LOG.debug("Header row created: {}", headerRow); csvWriter.writeNext(groupRow); csvWriter.writeNext(headerRow.toArray(groupRow)); writeObject(csvWriter, assistant, groupRow.length); } public Comparator<Object> compareField() { return new Comparator<Object>() { @Override public int compare(Object field1, Object field2) { return ((MetaField) field1).getName().compareTo(((MetaField) field2).getName()); } }; } private void writeObject(CSVWriter csvWriter, PermissionAssistant assistant, Integer size) { String language = assistant.getLanguage(); language = language != null ? language : "en"; LOG.debug("Language selected: {}", language); ResourceBundle bundle = I18n.getBundle(new Locale(language)); for (MetaModel object : assistant.getObjectSet()) { String[] row = new String[size]; row[0] = object.getFullName(); csvWriter.writeNext(row); List<MetaField> fieldList = object.getMetaFields(); Collections.sort(fieldList, compareField()); for (MetaField field : fieldList) { row = new String[size]; row[1] = field.getName(); String title = field.getLabel(); if (!Strings.isNullOrEmpty(title)) { title = bundle.getString(title); } row[2] = title; csvWriter.writeNext(row); } } } private boolean checkHeaderRow(String[] headerRow) { @SuppressWarnings("serial") List<String> headerList = new ArrayList<String>() { { add("Object"); add("Field"); add("Title"); } }; Integer count = 3; while (count < headerRow.length) { headerList.addAll(groupHeader); count += 8; } LOG.debug("Standard Headers: {}", headerList); String[] headers = headerList.toArray(new String[headerList.size()]); LOG.debug("File Headers: {}", Arrays.asList(headerRow)); return Arrays.equals(headers, headerRow); } public String importPermissions(PermissionAssistant permissionAssistant) { try { MetaFile metaFile = permissionAssistant.getMetaFile(); File csvFile = MetaFiles.getPath(metaFile).toFile(); CSVReader csvReader = new CSVReader(new FileReader(csvFile), ';'); String[] groupRow = csvReader.readNext(); if (groupRow == null || groupRow.length < 11) { errorLog = I18n.get(IMessage.BAD_FILE); } String[] headerRow = csvReader.readNext(); if (headerRow == null) { errorLog = I18n.get(IMessage.NO_HEADER); } if (!checkHeaderRow(headerRow)) { errorLog = I18n.get(IMessage.BAD_HEADER) + Arrays.asList(headerRow); } if (!errorLog.equals("")) { csvReader.close(); return errorLog; } Map<String, Group> groupMap = checkBadGroups(groupRow); Map<String, MetaPermission> metaPermissionDict = new HashMap<String, MetaPermission>(); processCSV(csvReader, groupRow, null, metaPermissionDict, groupMap); saveGroups(groupMap); } catch (Exception e) { e.printStackTrace(); errorLog += "\n" + String.format(I18n.get(IMessage.ERR_IMPORT_WITH_MSG), e.getMessage()); } return errorLog; } @Transactional public void saveGroups(Map<String, Group> groupMap) { for (Group group : groupMap.values()) { groupRepository.save(group); } } private Map<String, Group> checkBadGroups(String[] groupRow) { List<String> badGroups = new ArrayList<String>(); Map<String, Group> groupMap = new HashMap<String, Group>(); for (Integer glen = 4; glen < groupRow.length; glen += 8) { String groupName = groupRow[glen]; Group group = groupRepository.all().filter("self.code = ?1", groupName).fetchOne(); if (group == null) { badGroups.add(groupName); } else { groupMap.put(groupName, group); } } if (!badGroups.isEmpty()) { errorLog += "\n" + String.format(I18n.get(IMessage.NO_GROUP), badGroups); } return groupMap; } private String checkObject(String objectName) { MetaModel model = modelRepository.all().filter("self.fullName = ?1", objectName).fetchOne(); if (model == null) { errorLog += "\n" + String.format(I18n.get(IMessage.NO_OBJECT), objectName); return null; } return objectName; } private void processCSV(CSVReader csvReader, String[] groupRow, String objectName, Map<String, MetaPermission> metaPermissionDict, Map<String, Group> groupMap) throws IOException { String[] row = csvReader.readNext(); if (row == null) { return; } for (Integer groupIndex = 4; groupIndex < row.length; groupIndex += 8) { String groupName = groupRow[groupIndex]; if (!groupMap.containsKey(groupName)) { continue; } String[] rowGroup = (String[]) Arrays.copyOfRange(row, groupIndex, groupIndex + 8); if (!Strings.isNullOrEmpty(groupName) && !Strings.isNullOrEmpty(row[0])) { objectName = checkObject(row[0]); if (objectName == null) { break; } metaPermissionDict.put(groupName, getMetaPermission(groupMap.get(groupName), objectName)); updatePermission(groupMap.get(groupName), objectName, rowGroup); } else if (objectName != null && !Strings.isNullOrEmpty(row[1])) { updateFieldPermission(metaPermissionDict.get(groupName), row[1], rowGroup); } } processCSV(csvReader, groupRow, objectName, metaPermissionDict, groupMap); } public MetaPermission getMetaPermission(Group group, String objectName) { String[] objectNames = objectName.split("\\."); String groupName = group.getCode(); String permName = groupName + "." + objectNames[objectNames.length - 1]; MetaPermission metaPermission = metaPermissionRepository.all().filter("self.name = ?1", permName) .fetchOne(); if (metaPermission == null) { LOG.debug("Create metaPermission group: {}, object: {}", groupName, objectName); metaPermission = new MetaPermission(); metaPermission.setName(permName); metaPermission.setObject(objectName); group.addMetaPermission(metaPermission); } return metaPermission; } public MetaPermission updateFieldPermission(MetaPermission metaPermission, String field, String[] row) { MetaPermissionRule permissionRule = ruleRepository.all() .filter("self.field = ?1 and self.metaPermission.name = ?2", field, metaPermission.getName()) .fetchOne(); if (permissionRule == null) { permissionRule = new MetaPermissionRule(); permissionRule.setMetaPermission(metaPermission); permissionRule.setField(field); } permissionRule.setCanRead(row[0].equalsIgnoreCase("x")); permissionRule.setCanWrite(row[1].equalsIgnoreCase("x")); permissionRule.setCanExport(row[4].equalsIgnoreCase("x")); permissionRule.setReadonlyIf(row[5]); permissionRule.setHideIf(row[6]); metaPermission.addRule(permissionRule); return metaPermission; } public void updatePermission(Group group, String objectName, String[] row) { String[] objectNames = objectName.split("\\."); String groupName = group.getCode(); String permName = groupName + "." + objectNames[objectNames.length - 1]; Permission permission = permissionRepository.all().filter("self.name = ?1", permName).fetchOne(); boolean newPermission = false; if (permission == null) { newPermission = true; permission = new Permission(); permission.setName(permName); permission.setObject(objectName); } permission.setCanRead(row[0].equalsIgnoreCase("x")); permission.setCanWrite(row[1].equalsIgnoreCase("x")); permission.setCanCreate(row[2].equalsIgnoreCase("x")); permission.setCanRemove(row[3].equalsIgnoreCase("x")); permission.setCanExport(row[4].equalsIgnoreCase("x")); if (newPermission) { group.addPermission(permission); } } }