/** * Copyright © 2002 Instituto Superior Técnico * * This file is part of FenixEdu Academic. * * FenixEdu Academic is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FenixEdu Academic 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>. */ package org.fenixedu.academic.bootstrap; import static java.util.Collections.singletonList; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import org.apache.commons.lang.StringUtils; import org.fenixedu.academic.bootstrap.FenixBootstrapper.SchoolSetupSection; import org.fenixedu.academic.domain.Country; import org.fenixedu.academic.domain.CurricularYear; import org.fenixedu.academic.domain.Department; import org.fenixedu.academic.domain.EvaluationConfiguration; import org.fenixedu.academic.domain.EvaluationSeason; import org.fenixedu.academic.domain.Installation; import org.fenixedu.academic.domain.Person; import org.fenixedu.academic.domain.accessControl.academicAdministration.AcademicOperationType; import org.fenixedu.academic.domain.accounting.serviceAgreementTemplates.AdministrativeOfficeServiceAgreementTemplate; import org.fenixedu.academic.domain.administrativeOffice.AdministrativeOffice; import org.fenixedu.academic.domain.contacts.EmailAddress; import org.fenixedu.academic.domain.contacts.PartyContact; import org.fenixedu.academic.domain.contacts.PartyContactType; import org.fenixedu.academic.domain.contacts.PartyContactValidationState; import org.fenixedu.academic.domain.organizationalStructure.AccountabilityType; import org.fenixedu.academic.domain.organizationalStructure.AccountabilityTypeEnum; import org.fenixedu.academic.domain.organizationalStructure.AggregateUnit; import org.fenixedu.academic.domain.organizationalStructure.CompetenceCourseGroupUnit; import org.fenixedu.academic.domain.organizationalStructure.CountryUnit; import org.fenixedu.academic.domain.organizationalStructure.DepartmentUnit; import org.fenixedu.academic.domain.organizationalStructure.Party; import org.fenixedu.academic.domain.organizationalStructure.PartyType; import org.fenixedu.academic.domain.organizationalStructure.PartyTypeEnum; import org.fenixedu.academic.domain.organizationalStructure.PlanetUnit; import org.fenixedu.academic.domain.organizationalStructure.SchoolUnit; import org.fenixedu.academic.domain.organizationalStructure.ScientificAreaUnit; import org.fenixedu.academic.domain.organizationalStructure.Unit; import org.fenixedu.academic.domain.organizationalStructure.UniversityUnit; import org.fenixedu.academic.domain.person.RoleType; import org.fenixedu.academic.domain.serviceRequests.InstitutionRegistryCodeGenerator; import org.fenixedu.academic.domain.space.SpaceUtils; import org.fenixedu.academic.domain.student.RegistrationProtocol; import org.fenixedu.academic.util.Bundle; import org.fenixedu.academic.util.MultiLanguageString; import org.fenixedu.bennu.core.bootstrap.AdminUserBootstrapper.AdminUserSection; import org.fenixedu.bennu.core.bootstrap.BootstrapError; import org.fenixedu.bennu.core.bootstrap.annotations.Bootstrap; import org.fenixedu.bennu.core.bootstrap.annotations.Bootstrapper; import org.fenixedu.bennu.core.bootstrap.annotations.Field; import org.fenixedu.bennu.core.bootstrap.annotations.Section; import org.fenixedu.bennu.core.domain.Bennu; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.groups.Group; import org.fenixedu.bennu.core.i18n.BundleUtil; import org.fenixedu.bennu.core.security.Authenticate; import org.fenixedu.bennu.core.util.CoreConfiguration; import org.fenixedu.bennu.portal.domain.PortalBootstrapper; import org.fenixedu.bennu.portal.domain.PortalBootstrapper.PortalSection; import org.fenixedu.commons.i18n.LocalizedString; import org.fenixedu.commons.i18n.LocalizedString.Builder; import org.fenixedu.spaces.domain.SpaceClassification; import org.joda.time.YearMonthDay; import pt.ist.standards.geographic.Planet; import com.google.common.collect.Lists; import com.google.gson.JsonParser; @Bootstrapper(sections = { SchoolSetupSection.class, PortalSection.class, AdminUserSection.class }, name = "bootstrapper.name", bundle = Bundle.APPLICATION, after = PortalBootstrapper.class) public class FenixBootstrapper { final static Locale PT = new Locale("pt"); final static Locale EN = new Locale("en"); @Bootstrap public static List<BootstrapError> boostrap(SchoolSetupSection schoolSetupSection, PortalSection portalSection, AdminUserSection adminSection) { if (Planet.getEarth().getByAlfa3(schoolSetupSection.getCountryCode()) == null || !Planet.getEarth().getByAlfa3(schoolSetupSection.getCountryCode()).alpha3.equals(schoolSetupSection .getCountryCode())) { return singletonList(new BootstrapError(SchoolSetupSection.class, "getCountryCode", "bootstrapper.error.contry", Bundle.APPLICATION)); } createManagerUser(adminSection, schoolSetupSection); createAcademicSpaceClassifications(); createPartyTypeEnums(); createAccountabilityTypeEnums(); createCountries(schoolSetupSection); createCurricularYearsAndSemesters(); createDistrictAndDistrictSubdivision(); createOrganizationalStructure(); EvaluationSeason normalSeason = createEvaluationSeason("EN", "RS", "NORMAL", true, false, false, false); EvaluationConfiguration.getInstance().setDefaultEvaluationSeason(normalSeason); createEvaluationSeason("MN", "GI", "IMPROVEMENT", false, true, false, false); createEvaluationSeason("AE", "SA", "SPECIAL_AUTHORIZATION", false, false, true, false); createEvaluationSeason("EE", "SS", "SPECIAL_SEASON", false, false, false, true); //new CreateExecutionYears().doIt(); //new CreateResources().doIt(); new CreateOrganizationalStructure().doIt(portalSection, schoolSetupSection); //new CreateDegrees().doIt(process); //new CreateCurricularPeriods().doIt(); //new CreateCurricularStructure().doIt(); //new CreateExecutionCourses().doIt(); //new CreateEvaluations().doIt(); createEmptyDegreeAndEmptyDegreeCurricularPlan(); createDefaultRegistrationProtocol(); Installation installation = Installation.getInstance(); installation.setInstituitionEmailDomain(schoolSetupSection.getSchoolEmailDomain()); installation.setInstituitionURL(schoolSetupSection.getSchoolURL()); if (Bennu.getInstance().getRootClassificationSet().isEmpty()) { Builder schoolSpaces = new LocalizedString.Builder(); CoreConfiguration.supportedLocales().stream().forEach(l -> schoolSpaces.with(l, SpaceUtils.SCHOOL_SPACES)); SpaceClassification sc = new SpaceClassification("1", schoolSpaces.build()); Builder campus = new LocalizedString.Builder(); CoreConfiguration.supportedLocales().stream().forEach(l -> campus.with(l, SpaceUtils.CAMPUS)); sc.addChildren(new SpaceClassification("1.1", campus.build())); Builder building = new LocalizedString.Builder(); CoreConfiguration.supportedLocales().stream().forEach(l -> building.with(l, SpaceUtils.BUILDING)); sc.addChildren(new SpaceClassification("1.2", building.build())); Builder floor = new LocalizedString.Builder(); CoreConfiguration.supportedLocales().stream().forEach(l -> floor.with(l, SpaceUtils.FLOOR)); sc.addChildren(new SpaceClassification("1.3", floor.build())); Builder roomSubdivision = new LocalizedString.Builder(); CoreConfiguration.supportedLocales().stream().forEach(l -> roomSubdivision.with(l, SpaceUtils.ROOM_SUBDIVISION)); sc.addChildren(new SpaceClassification("1.4", roomSubdivision.build())); Builder room = new LocalizedString.Builder(); CoreConfiguration.supportedLocales().stream().forEach(l -> room.with(l, SpaceUtils.ROOM)); sc.addChildren(new SpaceClassification("1.4", room.build())); } return Lists.newArrayList(); } private static EvaluationSeason createEvaluationSeason(final String ptCode, final String enCode, final String nameKey, final boolean normal, final boolean improvement, final boolean specialAuthorization, final boolean special) { final LocalizedString acronym = new LocalizedString.Builder().with(Locale.forLanguageTag("pt-PT"), ptCode) .with(Locale.forLanguageTag("en-GB"), enCode).build(); return new EvaluationSeason(acronym, BundleUtil.getLocalizedString(Bundle.ENUMERATION, nameKey), normal, improvement, specialAuthorization, special); } private static void createDefaultRegistrationProtocol() { LocalizedString description = LocalizedString.fromJson(new JsonParser().parse("{\"pt-PT\":\"Normal\",\"en-GB\":\"Normal\"}")); RegistrationProtocol registrationProtocol = new RegistrationProtocol("NORMAL", description, true, true, true, false, false, false, false, false, false, true, false); } public static class CreateOrganizationalStructure { public void doIt(PortalSection portalSection, SchoolSetupSection schoolSetupSection) { final CountryUnit countryUnit = getCountryUnit(Country.readDefault().getName()); final UniversityUnit universityUnit = createUniversityUnit(countryUnit, schoolSetupSection.getUniversityName(), schoolSetupSection.getUniversityAcronym()); final SchoolUnit institutionUnit = createSchoolUnit(universityUnit, portalSection.getOrganizationName(), schoolSetupSection.getSchoolAcronym()); Bennu.getInstance().setInstitutionUnit(institutionUnit); setRegistryGenerator(institutionUnit); final AggregateUnit serviceUnits = createAggregateUnit(institutionUnit, "Services"); //createServiceUnits(serviceUnits); final AggregateUnit departmentUnits = createAggregateUnit(institutionUnit, "Departments"); //createDepartmentUnits(departmentUnits); final AggregateUnit degreeUnits = createAggregateUnit(institutionUnit, "Degrees"); //createDegreeUnits(degreeUnits); } private void setRegistryGenerator(SchoolUnit institutionUnit) { institutionUnit.setRegistryCodeGenerator(new InstitutionRegistryCodeGenerator()); } private CountryUnit getCountryUnit(final String countryUnitName) { for (final Party party : Bennu.getInstance().getPartysSet()) { if (party.isCountryUnit()) { final CountryUnit countryUnit = (CountryUnit) party; if (countryUnit.getName().equalsIgnoreCase(countryUnitName)) { return countryUnit; } } } return null; } private UniversityUnit createUniversityUnit(final CountryUnit countryUnit, final String universityName, final String universityAcronym) { return UniversityUnit.createNewUniversityUnit(new MultiLanguageString(Locale.getDefault(), universityName), null, null, universityAcronym, new YearMonthDay(), null, countryUnit, null, null, false, null); } private AggregateUnit createAggregateUnit(final Unit parentUnit, final String unitName) { return AggregateUnit.createNewAggregateUnit(new MultiLanguageString(Locale.getDefault(), unitName), null, null, null, new YearMonthDay(), null, parentUnit, AccountabilityType.readByType(AccountabilityTypeEnum.ORGANIZATIONAL_STRUCTURE), null, null, Boolean.FALSE, null); } private SchoolUnit createSchoolUnit(final UniversityUnit universityUnit, final String universityName, final String universityAcronym) { return SchoolUnit.createNewSchoolUnit(new MultiLanguageString(Locale.getDefault(), universityName), null, null, universityAcronym, new YearMonthDay(), null, universityUnit, null, null, Boolean.FALSE, null); } private void createServiceUnits(final AggregateUnit serviceUnits) { AdministrativeOffice administrativeOffice = new AdministrativeOffice(); Unit.createNewUnit(new MultiLanguageString(Locale.getDefault(), "Office"), null, null, null, new YearMonthDay(), null, serviceUnits, AccountabilityType.readByType(AccountabilityTypeEnum.ADMINISTRATIVE_STRUCTURE), null, null, administrativeOffice, Boolean.FALSE, null); new AdministrativeOfficeServiceAgreementTemplate(administrativeOffice); } private void createDepartmentUnits(final AggregateUnit departmentUnits) { for (int i = 0; i < 5; i++) { createDepartment(departmentUnits, i); } } private void createDepartment(final AggregateUnit departmentUnits, final int i) { final Department department = new Department(); department.setCode(getDepartmentCode(i)); final String departmentName = getDepartmentName(i); department.setName(departmentName); department.setRealName(departmentName); department.setCompetenceCourseMembersGroup(getCompetenceCourseMembersGroup()); final DepartmentUnit departmentUnit = createDepartmentUnut(departmentUnits, 3020 + i, department); department.setDepartmentUnit(departmentUnit); createCompetenceCourseGroupUnit(departmentUnit); } private int areaCounter = 0; private void createCompetenceCourseGroupUnit(final DepartmentUnit departmentUnit) { final ScientificAreaUnit scientificAreaUnit = ScientificAreaUnit.createNewInternalScientificArea(new MultiLanguageString(Locale.getDefault(), "Scientific Area"), null, null, "Code" + areaCounter++, new YearMonthDay(), null, departmentUnit, AccountabilityType.readByType(AccountabilityTypeEnum.ACADEMIC_STRUCTURE), null, null, Boolean.FALSE, null); CompetenceCourseGroupUnit.createNewInternalCompetenceCourseGroupUnit(new MultiLanguageString(Locale.getDefault(), "Competence Courses"), null, null, null, new YearMonthDay(), null, scientificAreaUnit, AccountabilityType .readByType(AccountabilityTypeEnum.ACADEMIC_STRUCTURE), null, null, Boolean.FALSE, null); } private DepartmentUnit createDepartmentUnut(final AggregateUnit departmentUnits, final int someNumber, final Department department) { return DepartmentUnit.createNewInternalDepartmentUnit(new MultiLanguageString(Locale.getDefault(), "Department Name " + someNumber), null, Integer.valueOf(2100 + someNumber), "DU" + someNumber, new YearMonthDay().minusMonths(1), null, departmentUnits, AccountabilityType.readByType(AccountabilityTypeEnum.ACADEMIC_STRUCTURE), null, department, null, Boolean.FALSE, null); } private org.fenixedu.bennu.core.groups.Group getCompetenceCourseMembersGroup() { return RoleType.TEACHER.actualGroup().or(Group.managers()); } private String getDepartmentName(final int i) { return "Department " + i; } private String getDepartmentCode(final int i) { return "DEP" + i; } } private static void createEmptyDegreeAndEmptyDegreeCurricularPlan() { // EmptyDegree.init(); // EmptyDegree.getInstance().setAdministrativeOffice(CreateTestData.administrativeOffice); // EmptyDegreeCurricularPlan.init(); } private static void createCurricularYearsAndSemesters() { new CurricularYear(Integer.valueOf(1), 2); new CurricularYear(Integer.valueOf(2), 2); new CurricularYear(Integer.valueOf(3), 2); new CurricularYear(Integer.valueOf(4), 2); new CurricularYear(Integer.valueOf(5), 2); new CurricularYear(Integer.valueOf(6), 2); } private static Country createCountries(SchoolSetupSection schoolSection) { Country defaultCountry = null; for (pt.ist.standards.geographic.Country metaData : Planet.getEarth().getPlaces()) { String localizedNamePT = null; try { localizedNamePT = metaData.getLocalizedName(PT); } catch (MissingResourceException e) { } String localizedNameEN = null; try { localizedNameEN = metaData.getLocalizedName(EN); } catch (MissingResourceException e) { } if (localizedNameEN == null && localizedNamePT == null) { continue; } if (localizedNamePT == null) { localizedNamePT = localizedNameEN; } if (localizedNameEN == null) { localizedNameEN = localizedNamePT; } String nationalityPT = null; try { nationalityPT = metaData.getNationality(PT); } catch (MissingResourceException e) { } String nationalityEN = null; try { nationalityEN = metaData.getNationality(EN); } catch (MissingResourceException e) { } if (nationalityPT == null) { if (nationalityEN == null) { nationalityPT = localizedNamePT; } else { nationalityPT = nationalityEN; } } if (nationalityEN == null) { if (nationalityPT == null) { nationalityEN = localizedNameEN; } else { nationalityEN = nationalityPT; } } final MultiLanguageString countryName = new MultiLanguageString(MultiLanguageString.pt, localizedNamePT); countryName.append(new MultiLanguageString(MultiLanguageString.en, localizedNameEN)); final String code = metaData.alpha2; final String threeLetterCode = metaData.alpha3; final Country country = new Country(countryName, new MultiLanguageString(MultiLanguageString.pt, nationalityPT).append(new MultiLanguageString( MultiLanguageString.en, nationalityEN)), code, threeLetterCode); if (StringUtils.equals(threeLetterCode, schoolSection.getCountryCode().toUpperCase())) { defaultCountry = country; } } defaultCountry.setDefaultCountry(Boolean.TRUE); return defaultCountry; } private static void createDistrictAndDistrictSubdivision() { } static void createManagerUser(AdminUserSection adminSection, SchoolSetupSection schoolSetupSection) { User adminUser = User.findByUsername(adminSection.getAdminUsername()); final Person person = new Person(adminUser.getProfile()); RoleType.grant(RoleType.SCIENTIFIC_COUNCIL, adminUser); RoleType.grant(RoleType.SPACE_MANAGER, adminUser); RoleType.grant(RoleType.SPACE_MANAGER_SUPER_USER, adminUser); RoleType.grant(RoleType.ACADEMIC_ADMINISTRATIVE_OFFICE, adminUser); RoleType.grant(RoleType.BOLONHA_MANAGER, adminUser); person.setCountry(Country.readDefault()); person.setCountryOfBirth(Country.readDefault()); EmailAddress.createEmailAddress(person, adminSection.getAdminUserEmail(), PartyContactType.PERSONAL, true, true, true, true); for (PartyContact partyContact : person.getPartyContactsSet()) { partyContact.setValid(); partyContact.getPartyContactValidation().setState(PartyContactValidationState.VALID); } Authenticate.mock(adminUser); AcademicOperationType.MANAGE_AUTHORIZATIONS.grant(adminUser); AcademicOperationType.MANAGE_ACADEMIC_CALENDARS.grant(adminUser); } private static void createAcademicSpaceClassifications() { LocalizedString.Builder campusNameBuilder = new LocalizedString.Builder(); CoreConfiguration.supportedLocales().stream().forEach(l -> campusNameBuilder.with(l, "Campus")); new SpaceClassification("1", campusNameBuilder.build()); } private static void createPartyTypeEnums() { for (final PartyTypeEnum partyTypeEnum : PartyTypeEnum.values()) { new PartyType(partyTypeEnum); } } private static void createAccountabilityTypeEnums() { for (final AccountabilityTypeEnum accountabilityTypeEnum : AccountabilityTypeEnum.values()) { new AccountabilityType(accountabilityTypeEnum, new MultiLanguageString(Locale.getDefault(), accountabilityTypeEnum.getName())); } } private static void createOrganizationalStructure() { final Bennu rootDomainObject = Bennu.getInstance(); final PlanetUnit planetUnit = PlanetUnit.createNewPlanetUnit(new MultiLanguageString(Locale.getDefault(), "Earth"), null, null, "E", new YearMonthDay(), null, null, null, null, false, null); rootDomainObject.setEarthUnit(planetUnit); createCountryUnits(rootDomainObject, planetUnit); } private static void createCountryUnits(final Bennu rootDomainObject, final PlanetUnit planetUnit) { for (final Country country : Country.readDistinctCountries()) { CountryUnit.createNewCountryUnit(new MultiLanguageString(Locale.getDefault(), country.getName()), null, null, country.getCode(), new YearMonthDay(), null, planetUnit, null, null, false, null); } } @Section(name = "bootstrapper.schoolSetup.name", description = "bootstrapper.schoolSetup.description", bundle = Bundle.APPLICATION) public static interface SchoolSetupSection { @Field(name = "bootstrapper.schoolSetup.universityName", hint = "bootstrapper.schoolSetup.universityName.hint", order = 1) public String getUniversityName(); @Field(name = "bootstrapper.schoolSetup.universityAcronym", hint = "bootstrapper.schoolSetup.universityAcronym.hint", order = 2) public String getUniversityAcronym(); @Field(name = "bootstrapper.schoolSetup.schoolAcronym", hint = "bootstrapper.schoolSetup.schoolAcronym.hint", order = 3) public String getSchoolAcronym(); @Field(name = "bootstrapper.schoolSetup.country", hint = "bootstrapper.schoolSetup.country.hint", order = 4) public String getCountryCode(); @Field(name = "bootstrapper.application.schoolDomain", hint = "bootstrapper.application.schoolDomain.hint", order = 5) public String getSchoolDomain(); @Field(name = "bootstrapper.application.schoolUrl", hint = "bootstrapper.application.schoolUrl.hint", order = 6) public String getSchoolURL(); @Field(name = "bootstrapper.application.schoolEmailDomain", hint = "bootstrapper.application.schoolEmailDomain.hint", order = 7) public String getSchoolEmailDomain(); } }