Update JGraphT.
Code refactoring.
This commit is contained in:
parent
4134315421
commit
3adb216e56
9 changed files with 1272 additions and 1137 deletions
|
|
@ -137,7 +137,7 @@
|
|||
<!-- JGraphT -->
|
||||
<dependency>
|
||||
<groupId>org.jgrapht</groupId>
|
||||
<artifactId>jgrapht-jdk1.5</artifactId>
|
||||
<artifactId>jgrapht-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Junit -->
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -444,6 +444,7 @@
|
|||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- TODO put it to main pom? -->
|
||||
<!-- Java mail -->
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
|
|
@ -488,7 +489,7 @@
|
|||
<!-- JGraphT -->
|
||||
<dependency>
|
||||
<groupId>org.jgrapht</groupId>
|
||||
<artifactId>jgrapht-jdk1.5</artifactId>
|
||||
<artifactId>jgrapht-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- jqPlot -->
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class I18nHelper {
|
|||
|
||||
private static Locale defaultLang = Locale.ENGLISH;
|
||||
|
||||
private static HashMap<Locale, I18n> localesCache = new HashMap<Locale, I18n>();
|
||||
private static HashMap<Locale, I18n> localesCache = new HashMap<>();
|
||||
|
||||
public static I18n getI18n() {
|
||||
setPreferredLocale();
|
||||
|
|
@ -51,12 +51,10 @@ public class I18nHelper {
|
|||
return localesCache.get(locale);
|
||||
}
|
||||
|
||||
I18n i18n = I18nFactory.getI18n(I18nHelper.class, locale,
|
||||
org.xnap.commons.i18n.I18nFactory.FALLBACK);
|
||||
I18n i18n = I18nFactory.getI18n(I18nHelper.class, locale, org.xnap.commons.i18n.I18nFactory.FALLBACK);
|
||||
|
||||
// The language returned is not the same as the requested by the user
|
||||
if (!locale.getLanguage().equals(
|
||||
i18n.getResources().getLocale().getLanguage())) {
|
||||
if ( !locale.getLanguage().equals(i18n.getResources().getLocale().getLanguage()) ) {
|
||||
// Force it to be default language
|
||||
i18n = getDefaultI18n();
|
||||
}
|
||||
|
|
@ -69,8 +67,7 @@ public class I18nHelper {
|
|||
Execution execution = Executions.getCurrent();
|
||||
if ( execution != null ) {
|
||||
Locale userLocale = getUserLocale();
|
||||
Charsets.setPreferredLocale((HttpSession) execution.getSession()
|
||||
.getNativeSession(), userLocale);
|
||||
Charsets.setPreferredLocale((HttpSession) execution.getSession().getNativeSession(), userLocale);
|
||||
if ( userLocale != null ) {
|
||||
Locales.setThreadLocal(userLocale);
|
||||
}
|
||||
|
|
@ -79,18 +76,17 @@ public class I18nHelper {
|
|||
|
||||
private static Locale getUserLocale() {
|
||||
User user = UserUtil.getUserFromSession();
|
||||
if (user != null) {
|
||||
return user.getApplicationLanguage().getLocale();
|
||||
}
|
||||
return null;
|
||||
|
||||
return (user != null) ? user.getApplicationLanguage().getLocale() : null;
|
||||
}
|
||||
|
||||
private static I18n getDefaultI18n() {
|
||||
I18n i18n = localesCache.get(defaultLang);
|
||||
|
||||
if ( i18n == null ) {
|
||||
i18n = I18nFactory.getI18n(I18nHelper.class, defaultLang,
|
||||
org.xnap.commons.i18n.I18nFactory.FALLBACK);
|
||||
i18n = I18nFactory.getI18n(I18nHelper.class, defaultLang, org.xnap.commons.i18n.I18nFactory.FALLBACK);
|
||||
}
|
||||
|
||||
return i18n;
|
||||
}
|
||||
|
||||
|
|
@ -114,8 +110,7 @@ public class I18nHelper {
|
|||
return getI18n().tr(text, o1, o2, o3);
|
||||
}
|
||||
|
||||
public static String _(String text, Object o1, Object o2, Object o3,
|
||||
Object o4) {
|
||||
public static String _(String text, Object o1, Object o2, Object o3, Object o4) {
|
||||
return getI18n().tr(text, o1, o2, o3, o4);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,8 +111,7 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
this.disabled = disabled;
|
||||
}
|
||||
|
||||
public CustomMenuItem(String name, String url,
|
||||
List<CustomMenuItem> children) {
|
||||
public CustomMenuItem(String name, String url, List<CustomMenuItem> children) {
|
||||
this.name = name;
|
||||
this.unencodedURL = url;
|
||||
this.encodedURL = Executions.getCurrent().encodeURL(url);
|
||||
|
|
@ -139,16 +138,18 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<CustomMenuItem> thisAndChildren() {
|
||||
List<CustomMenuItem> items = new ArrayList<CustomMenuItem>();
|
||||
List<CustomMenuItem> items = new ArrayList<>();
|
||||
items.add(this);
|
||||
items.addAll(children);
|
||||
for (CustomMenuItem child : children) {
|
||||
items.addAll(child.children);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
|
@ -167,14 +168,12 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
}
|
||||
|
||||
private static IGlobalViewEntryPoints findGlobalViewEntryPoints() {
|
||||
return (IGlobalViewEntryPoints) getSpringContext().getBean(
|
||||
"globalView", IGlobalViewEntryPoints.class);
|
||||
return getSpringContext().getBean("globalView", IGlobalViewEntryPoints.class);
|
||||
}
|
||||
|
||||
private static WebApplicationContext getSpringContext() {
|
||||
Execution current = Executions.getCurrent();
|
||||
HttpServletRequest request = (HttpServletRequest) current
|
||||
.getNativeRequest();
|
||||
HttpServletRequest request = (HttpServletRequest) current.getNativeRequest();
|
||||
ServletContext context = request.getSession().getServletContext();
|
||||
|
||||
return WebApplicationContextUtils.getWebApplicationContext(context);
|
||||
|
|
@ -185,7 +184,7 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
private IGlobalViewEntryPoints globalView;
|
||||
|
||||
public CustomMenuController() {
|
||||
this.firstLevel = new ArrayList<CustomMenuItem>();
|
||||
this.firstLevel = new ArrayList<>();
|
||||
this.globalView = findGlobalViewEntryPoints();
|
||||
initializeMenu();
|
||||
activateCurrentOne();
|
||||
|
|
@ -193,23 +192,33 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
}
|
||||
|
||||
private void activateCurrentOne() {
|
||||
String requestPath = Executions.getCurrent().getDesktop()
|
||||
.getRequestPath();
|
||||
String requestPath = Executions.getCurrent().getDesktop().getRequestPath();
|
||||
|
||||
for (CustomMenuItem ci : this.firstLevel) {
|
||||
|
||||
if ( ci.contains(requestPath) ) {
|
||||
|
||||
ci.setActive(true);
|
||||
|
||||
for (CustomMenuItem child : ci.children) {
|
||||
|
||||
if ( child.contains(requestPath) ) {
|
||||
|
||||
child.setActive(true);
|
||||
|
||||
for (CustomMenuItem c : child.children) {
|
||||
|
||||
if ( c.contains(requestPath) ) {
|
||||
|
||||
c.setActive(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -225,27 +234,26 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
return OnZKDesktopRegistry.getLocatorFor(IMenuItemsRegister.class);
|
||||
}
|
||||
|
||||
private CustomMenuController topItem(String name, String url,
|
||||
String helpUri, Collection<? extends CustomMenuItem> items) {
|
||||
return topItem(name, url, helpUri,
|
||||
items.toArray(new CustomMenuItem[items.size()]));
|
||||
private CustomMenuController topItem(String name, String url, String helpUri,
|
||||
Collection<? extends CustomMenuItem> items) {
|
||||
|
||||
return topItem(name, url, helpUri, items.toArray(new CustomMenuItem[items.size()]));
|
||||
}
|
||||
|
||||
private CustomMenuController topItem(String name, String url,
|
||||
String helpUri,
|
||||
CustomMenuItem... items) {
|
||||
private CustomMenuController topItem(String name, String url, String helpUri, CustomMenuItem... items) {
|
||||
return topItem(name, url, helpUri, false, items);
|
||||
}
|
||||
|
||||
private CustomMenuController topItem(String name, String url,
|
||||
String helpLink,
|
||||
boolean disabled, CustomMenuItem... items) {
|
||||
private CustomMenuController topItem(String name, String url, String helpLink, boolean disabled,
|
||||
CustomMenuItem... items) {
|
||||
|
||||
CustomMenuItem parent = new CustomMenuItem(name, url, disabled);
|
||||
parent.setHelpLink(helpLink);
|
||||
this.firstLevel.add(parent);
|
||||
for (CustomMenuItem child : items) {
|
||||
parent.appendChildren(child);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -253,296 +261,316 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
return new CustomMenuItem(name, url, helpLink);
|
||||
}
|
||||
|
||||
private CustomMenuItem subItem(String name, ICapture urlCapture,
|
||||
String helpLink) {
|
||||
return new CustomMenuItem(name, EntryPointsHandler.capturePath(urlCapture),
|
||||
helpLink);
|
||||
private CustomMenuItem subItem(String name, ICapture urlCapture, String helpLink) {
|
||||
return new CustomMenuItem(name, EntryPointsHandler.capturePath(urlCapture), helpLink);
|
||||
}
|
||||
|
||||
public void initializeMenu() {
|
||||
List<CustomMenuItem> planningItems = new ArrayList<CustomMenuItem>();
|
||||
List<CustomMenuItem> planningItems = new ArrayList<>();
|
||||
if ( SecurityUtils.isSuperuserOrRolePlanningOrHasAnyAuthorization() ) {
|
||||
planningItems.add(subItem(_("Company view"), new ICapture() {
|
||||
|
||||
planningItems.add(
|
||||
subItem(
|
||||
_("Company view"),
|
||||
new ICapture() {
|
||||
@Override
|
||||
public void capture() {
|
||||
globalView.goToCompanyScheduling();
|
||||
}
|
||||
}, "01-introducion.html"));
|
||||
planningItems.add(subItem(_("Projects"), new ICapture() {
|
||||
},
|
||||
"01-introducion.html"));
|
||||
|
||||
planningItems.add(subItem(
|
||||
_("Projects"),
|
||||
new ICapture() {
|
||||
@Override
|
||||
public void capture() {
|
||||
globalView.goToOrdersList();
|
||||
}
|
||||
}, "01-introducion.html#id2"));
|
||||
},
|
||||
"01-introducion.html#id2"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_PLANNING) ) {
|
||||
planningItems.add(subItem(_("Resources Load"), new ICapture() {
|
||||
planningItems.add(subItem(
|
||||
_("Resources Load"),
|
||||
new ICapture() {
|
||||
@Override
|
||||
public void capture() {
|
||||
globalView.goToCompanyLoad();
|
||||
}
|
||||
}, "01-introducion.html#id1"));
|
||||
planningItems.add(subItem(_("Queue-based Resources"), new ICapture() {
|
||||
},
|
||||
"01-introducion.html#id1"));
|
||||
|
||||
planningItems.add(subItem(
|
||||
_("Queue-based Resources"),
|
||||
new ICapture() {
|
||||
@Override
|
||||
public void capture() {
|
||||
globalView.goToLimitingResources();
|
||||
}
|
||||
}, "01-introducion.html"));
|
||||
},
|
||||
"01-introducion.html"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TEMPLATES) ) {
|
||||
planningItems.add(subItem(_("Templates"),
|
||||
"/templates/templates.zul", ""));
|
||||
planningItems.add(subItem(_("Templates"), "/templates/templates.zul", ""));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_IMPORT_PROJECTS) ) {
|
||||
// In order of see the Import project option in the menu
|
||||
planningItems.add(subItem(_("Import project"),
|
||||
"/orders/imports/projectImport.zul", ""));
|
||||
planningItems.add(subItem(_("Import project"), "/orders/imports/projectImport.zul", ""));
|
||||
}
|
||||
|
||||
|
||||
//TODO There is some problem here!
|
||||
/*planningItems.add(subItem(_("Logs"), new ICapture() {
|
||||
@Override
|
||||
public void capture() {
|
||||
globalView.goToLogs();
|
||||
}
|
||||
}, "01-asd"));*/
|
||||
|
||||
if ( !planningItems.isEmpty() ) {
|
||||
topItem(_("Planning"), "/planner/index.zul", "", planningItems);
|
||||
}
|
||||
|
||||
List<CustomMenuItem> resourcesItems = new ArrayList<CustomMenuItem>();
|
||||
List<CustomMenuItem> resourcesItems = new ArrayList<>();
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_WORKERS) ) {
|
||||
resourcesItems.add(subItem(_("Workers"),
|
||||
resourcesItems.add(subItem(
|
||||
_("Workers"),
|
||||
"/resources/worker/worker.zul",
|
||||
"05-recursos.html#xesti-n-de-traballadores"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_MACHINES) ) {
|
||||
resourcesItems.add(subItem(_("Machines"),
|
||||
resourcesItems.add(subItem(
|
||||
_("Machines"),
|
||||
"/resources/machine/machines.zul",
|
||||
"05-recursos.html#xesti-n-de-m-quinas"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_VIRTUAL_WORKERS)) {
|
||||
resourcesItems.add(subItem(_("Virtual Workers"),
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_VIRTUAL_WORKERS) ) {
|
||||
resourcesItems.add(subItem(
|
||||
_("Virtual Workers"),
|
||||
"/resources/worker/virtualWorkers.zul",
|
||||
"05-recursos.html#xesti-n-de-traballadores"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_CALENDARS) ) {
|
||||
resourcesItems.add(subItem(_("Calendars"),
|
||||
"/calendars/calendars.zul", "03-calendarios.html"));
|
||||
resourcesItems.add(subItem(_("Calendars"), "/calendars/calendars.zul", "03-calendarios.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_CALENDAR_EXCEPTION_DAYS)) {
|
||||
resourcesItems.add(subItem(_("Calendar Exception Days"),
|
||||
"/excetiondays/exceptionDays.zul", ""));
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_CALENDAR_EXCEPTION_DAYS) ) {
|
||||
resourcesItems.add(subItem(_("Calendar Exception Days"), "/excetiondays/exceptionDays.zul", ""));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_CRITERIA) ) {
|
||||
resourcesItems.add(subItem(_("Criteria"),
|
||||
"/resources/criterions/criterions.zul",
|
||||
"02-criterios.html#id1"));
|
||||
resourcesItems.add(subItem(_("Criteria"), "/resources/criterions/criterions.zul", "02-criterios.html#id1"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_PROGRESS_TYPES)) {
|
||||
resourcesItems.add(subItem(_("Progress Types"),
|
||||
"/advance/advanceTypes.zul", "04-avances.html#id1"));
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_PROGRESS_TYPES) ) {
|
||||
resourcesItems.add(subItem(_("Progress Types"), "/advance/advanceTypes.zul", "04-avances.html#id1"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_LABELS) ) {
|
||||
resourcesItems.add(subItem(_("Labels"), "/labels/labelTypes.zul",
|
||||
"10-etiquetas.html"));
|
||||
resourcesItems.add(subItem(_("Labels"), "/labels/labelTypes.zul", "10-etiquetas.html"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_MATERIALS) ) {
|
||||
resourcesItems.add(subItem(_("Materials"),
|
||||
resourcesItems.add(subItem(
|
||||
_("Materials"),
|
||||
"/materials/materials.zul",
|
||||
"11-materiales.html#administraci-n-de-materiais"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_MATERIAL_UNITS)) {
|
||||
resourcesItems.add(subItem(_("Material Units"),
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_MATERIAL_UNITS) ) {
|
||||
resourcesItems.add(subItem(
|
||||
_("Material Units"),
|
||||
"/unittypes/unitTypes.zul",
|
||||
"11-materiales.html#administraci-n-de-materiais"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_QUALITY_FORMS) ) {
|
||||
resourcesItems
|
||||
.add(subItem(_("Quality Forms"),
|
||||
resourcesItems.add(subItem(
|
||||
_("Quality Forms"),
|
||||
"/qualityforms/qualityForms.zul",
|
||||
"12-formularios-calidad.html#administraci-n-de-formularios-de-calidade"));
|
||||
}
|
||||
|
||||
if ( !resourcesItems.isEmpty() ) {
|
||||
topItem(_("Resources"), "/resources/worker/worker.zul", "",
|
||||
resourcesItems);
|
||||
topItem(_("Resources"), "/resources/worker/worker.zul", "", resourcesItems);
|
||||
}
|
||||
|
||||
List<CustomMenuItem> costItems = new ArrayList<CustomMenuItem>();
|
||||
List<CustomMenuItem> costItems = new ArrayList<>();
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TIMESHEETS) ) {
|
||||
costItems.add(subItem(_("Timesheets"),
|
||||
"/workreports/workReport.zul", "09-partes.html#id3"));
|
||||
costItems.add(subItem(_("Timesheets"), "/workreports/workReport.zul", "09-partes.html#id3"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_TIMESHEETS_TEMPLATES)) {
|
||||
costItems.add(subItem(_("Timesheets Templates"),
|
||||
"/workreports/workReportTypes.zul", "09-partes.html#id2"));
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TIMESHEETS_TEMPLATES) ) {
|
||||
costItems.add(subItem(
|
||||
_("Timesheets Templates"),
|
||||
"/workreports/workReportTypes.zul",
|
||||
"09-partes.html#id2"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_TIMESHEET_LINES_LIST)) {
|
||||
costItems.add(subItem(_("Timesheet Lines List"),
|
||||
"/workreports/workReportQuery.zul", "09-partes.html#id4"));
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TIMESHEET_LINES_LIST) ) {
|
||||
costItems.add(subItem(
|
||||
_("Timesheet Lines List"),
|
||||
"/workreports/workReportQuery.zul",
|
||||
"09-partes.html#id4"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_EXPENSES) ) {
|
||||
costItems.add(subItem(_("Expenses"),
|
||||
"/expensesheet/expenseSheet.zul", ""));
|
||||
costItems.add(subItem(_("Expenses"), "/expensesheet/expenseSheet.zul", ""));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_COST_CATEGORIES)) {
|
||||
costItems.add(subItem(_("Cost Categories"),
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_COST_CATEGORIES) ) {
|
||||
costItems.add(subItem(
|
||||
_("Cost Categories"),
|
||||
"/costcategories/costCategory.zul",
|
||||
"14-custos.html#categor-as-de-custo"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_HOURS_TYPES) ) {
|
||||
costItems.add(subItem(_("Hours Types"),
|
||||
costItems.add(subItem(
|
||||
_("Hours Types"),
|
||||
"/typeofworkhours/typeOfWorkHours.zul",
|
||||
"14-custos.html#administraci-n-de-horas-traballadas"));
|
||||
}
|
||||
|
||||
if ( !costItems.isEmpty() ) {
|
||||
topItem(_("Cost"), "/workreports/workReport.zul", "", costItems);
|
||||
}
|
||||
|
||||
List<CustomMenuItem> configurationItems = new ArrayList<CustomMenuItem>();
|
||||
List<CustomMenuItem> configurationItems = new ArrayList<>();
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_MAIN_SETTINGS) ) {
|
||||
configurationItems
|
||||
.add(subItem(_("Main Settings"),
|
||||
configurationItems.add(subItem(
|
||||
_("Main Settings"),
|
||||
"/common/configuration.zul",
|
||||
"16-ldap-authentication.html"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS) ) {
|
||||
configurationItems.add(subItem(_("User Accounts"),
|
||||
configurationItems.add(subItem(
|
||||
_("User Accounts"),
|
||||
"/users/users.zul",
|
||||
"13-usuarios.html#administraci-n-de-usuarios"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_PROFILES) ) {
|
||||
configurationItems.add(subItem(_("Profiles"),
|
||||
configurationItems.add(subItem(
|
||||
_("Profiles"),
|
||||
"/profiles/profiles.zul",
|
||||
"13-usuarios.html#administraci-n-de-perfiles"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_JOB_SCHEDULING)) {
|
||||
configurationItems.add(subItem(_("Job Scheduling"),
|
||||
"/common/job_scheduling.zul",
|
||||
"19-scheduler.html"));
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_JOB_SCHEDULING) ) {
|
||||
configurationItems.add(subItem(_("Job Scheduling"), "/common/job_scheduling.zul", "19-scheduler.html"));
|
||||
}
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_EDIT_EMAIL_TEMPLATES) ) {
|
||||
configurationItems.add(subItem(_("Edit E-mail Templates"),
|
||||
configurationItems.add(subItem(
|
||||
_("Edit E-mail Templates"),
|
||||
"/email/email_templates.zul",
|
||||
"email-templates.html"));
|
||||
}
|
||||
|
||||
if ( !configurationItems.isEmpty() ) {
|
||||
topItem(_("Configuration"), "/common/configuration.zul", "",
|
||||
configurationItems);
|
||||
topItem(_("Configuration"), "/common/configuration.zul", "", configurationItems);
|
||||
}
|
||||
|
||||
List<CustomMenuItem> communicationsItems = new ArrayList<CustomMenuItem>();
|
||||
List<CustomMenuItem> communicationsItems = new ArrayList<>();
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_COMPANIES) ) {
|
||||
communicationsItems.add(subItem(_("Companies"),
|
||||
"/externalcompanies/externalcompanies.zul", ""));
|
||||
communicationsItems.add(subItem(_("Companies"), "/externalcompanies/externalcompanies.zul", ""));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_SEND_TO_SUBCONTRACTORS)) {
|
||||
communicationsItems.add(subItem(_("Send To Subcontractors"),
|
||||
"/subcontract/subcontractedTasks.zul", ""));
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_SEND_TO_SUBCONTRACTORS) ) {
|
||||
communicationsItems.add(subItem(_("Send To Subcontractors"), "/subcontract/subcontractedTasks.zul", ""));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_RECEIVED_FROM_SUBCONTRACTORS)) {
|
||||
communicationsItems.add(subItem(_("Received From Subcontractors"),
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_RECEIVED_FROM_SUBCONTRACTORS) ) {
|
||||
communicationsItems.add(subItem(
|
||||
_("Received From Subcontractors"),
|
||||
"/subcontract/subcontractorCommunications.zul", ""));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_SEND_TO_CUSTOMERS)) {
|
||||
communicationsItems.add(subItem(_("Send To Customers"),
|
||||
"/subcontract/reportAdvances.zul", ""));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_RECEIVED_FROM_CUSTOMERS)) {
|
||||
communicationsItems.add(subItem(_("Received From Customers"),
|
||||
"/subcontract/customerCommunications.zul", ""));
|
||||
}
|
||||
if (!communicationsItems.isEmpty()) {
|
||||
topItem(_("Communications"),
|
||||
"/externalcompanies/externalcompanies.zul", "",
|
||||
communicationsItems);
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_SEND_TO_CUSTOMERS) ) {
|
||||
communicationsItems.add(subItem(_("Send To Customers"), "/subcontract/reportAdvances.zul", ""));
|
||||
}
|
||||
|
||||
List<CustomMenuItem> reportsItems = new ArrayList<CustomMenuItem>();
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_HOURS_WORKED_PER_RESOURCE_REPORT)) {
|
||||
reportsItems.add(subItem(_("Hours Worked Per Resource"),
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_RECEIVED_FROM_CUSTOMERS) ) {
|
||||
communicationsItems.add(subItem(
|
||||
_("Received From Customers"),
|
||||
"/subcontract/customerCommunications.zul", ""));
|
||||
}
|
||||
|
||||
if ( !communicationsItems.isEmpty() ) {
|
||||
topItem(_("Communications"), "/externalcompanies/externalcompanies.zul", "", communicationsItems);
|
||||
}
|
||||
|
||||
List<CustomMenuItem> reportsItems = new ArrayList<>();
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_HOURS_WORKED_PER_RESOURCE_REPORT) ) {
|
||||
reportsItems.add(subItem(
|
||||
_("Hours Worked Per Resource"),
|
||||
"/reports/hoursWorkedPerWorkerReport.zul",
|
||||
"15-1-report-hours-worked-by-resource.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_TOTAL_WORKED_HOURS_BY_RESOURCE_IN_A_MONTH_REPORT)) {
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TOTAL_WORKED_HOURS_BY_RESOURCE_IN_A_MONTH_REPORT) ) {
|
||||
reportsItems.add(subItem(
|
||||
_("Total Worked Hours By Resource In A Month"),
|
||||
"/reports/hoursWorkedPerWorkerInAMonthReport.zul",
|
||||
"15-2-total-hours-by-resource-month.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_WORK_AND_PROGRESS_PER_PROJECT_REPORT)) {
|
||||
reportsItems.add(subItem(_("Work And Progress Per Project"),
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_WORK_AND_PROGRESS_PER_PROJECT_REPORT) ) {
|
||||
reportsItems.add(subItem(
|
||||
_("Work And Progress Per Project"),
|
||||
"/reports/schedulingProgressPerOrderReport.zul",
|
||||
"15-3-work-progress-per-project.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_WORK_AND_PROGRESS_PER_TASK_REPORT)) {
|
||||
reportsItems.add(subItem(_("Work And Progress Per Task"),
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_WORK_AND_PROGRESS_PER_TASK_REPORT) ) {
|
||||
reportsItems.add(subItem(
|
||||
_("Work And Progress Per Task"),
|
||||
"/reports/workingProgressPerTaskReport.zul",
|
||||
"15-informes.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_ESTIMATED_PLANNED_HOURS_PER_TASK_REPORT)) {
|
||||
reportsItems.add(subItem(_("Estimated/Planned Hours Per Task"),
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_ESTIMATED_PLANNED_HOURS_PER_TASK_REPORT) ) {
|
||||
reportsItems.add(subItem(
|
||||
_("Estimated/Planned Hours Per Task"),
|
||||
"/reports/completedEstimatedHoursPerTask.zul",
|
||||
"15-informes.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_PROJECT_COSTS_REPORT)) {
|
||||
reportsItems.add(subItem(_("Project Costs"),
|
||||
"/reports/orderCostsPerResource.zul", "15-informes.html"));
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_PROJECT_COSTS_REPORT) ) {
|
||||
reportsItems.add(subItem(_("Project Costs"), "/reports/orderCostsPerResource.zul", "15-informes.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_TASK_SCHEDULING_STATUS_IN_PROJECT_REPORT)) {
|
||||
reportsItems.add(subItem(_("Task Scheduling Status In Project"),
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TASK_SCHEDULING_STATUS_IN_PROJECT_REPORT) ) {
|
||||
reportsItems.add(subItem(
|
||||
_("Task Scheduling Status In Project"),
|
||||
"/reports/workingArrangementsPerOrderReport.zul",
|
||||
"15-informes.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_MATERIALS_NEED_AT_DATE_REPORT)) {
|
||||
reportsItems.add(subItem(_("Materials Needed At Date"),
|
||||
"/reports/timeLineMaterialReport.zul", "15-informes.html"));
|
||||
}
|
||||
if (SecurityUtils
|
||||
.isSuperuserOrUserInRoles(UserRole.ROLE_PROJECT_STATUS_REPORT)) {
|
||||
reportsItems.add(subItem(_("Project Status"),
|
||||
"/reports/projectStatusReport.zul", "15-informes.html"));
|
||||
}
|
||||
if (!reportsItems.isEmpty()) {
|
||||
topItem(_("Reports"), "/reports/hoursWorkedPerWorkerReport.zul",
|
||||
"", reportsItems);
|
||||
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_MATERIALS_NEED_AT_DATE_REPORT) ) {
|
||||
reportsItems.add(subItem(
|
||||
_("Materials Needed At Date"),
|
||||
"/reports/timeLineMaterialReport.zul",
|
||||
"15-informes.html"));
|
||||
}
|
||||
|
||||
List<CustomMenuItem> personalAreaItems = new ArrayList<CustomMenuItem>();
|
||||
if (SecurityUtils.isUserInRole(UserRole.ROLE_BOUND_USER)) {
|
||||
personalAreaItems.add(subItem(_("Home"),
|
||||
"/myaccount/userDashboard.zul", ""));
|
||||
if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_PROJECT_STATUS_REPORT) ) {
|
||||
reportsItems.add(subItem(_("Project Status"), "/reports/projectStatusReport.zul", "15-informes.html"));
|
||||
}
|
||||
personalAreaItems.add(subItem(_("Preferences"),
|
||||
"/myaccount/settings.zul", ""));
|
||||
personalAreaItems.add(subItem(_("Change Password"),
|
||||
"/myaccount/changePassword.zul", ""));
|
||||
topItem(_("Personal area"), "/myaccount/userDashboard.zul", "",
|
||||
personalAreaItems);
|
||||
|
||||
if ( !reportsItems.isEmpty() ) {
|
||||
topItem(_("Reports"), "/reports/hoursWorkedPerWorkerReport.zul", "", reportsItems);
|
||||
}
|
||||
|
||||
List<CustomMenuItem> personalAreaItems = new ArrayList<>();
|
||||
if ( SecurityUtils.isUserInRole(UserRole.ROLE_BOUND_USER) ) {
|
||||
personalAreaItems.add(subItem(_("Home"), "/myaccount/userDashboard.zul", ""));
|
||||
}
|
||||
|
||||
personalAreaItems.add(subItem(_("Preferences"), "/myaccount/settings.zul", ""));
|
||||
personalAreaItems.add(subItem(_("Change Password"), "/myaccount/changePassword.zul", ""));
|
||||
topItem(_("Personal area"), "/myaccount/userDashboard.zul", "", personalAreaItems);
|
||||
}
|
||||
|
||||
private Vbox getRegisteredItemsInsertionPoint() {
|
||||
|
|
@ -554,15 +582,24 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
}
|
||||
|
||||
public List<CustomMenuItem> getBreadcrumbsPath() {
|
||||
List<CustomMenuItem> breadcrumbsPath = new ArrayList<CustomMenuItem>();
|
||||
List<CustomMenuItem> breadcrumbsPath = new ArrayList<>();
|
||||
|
||||
for (CustomMenuItem ci : this.firstLevel) {
|
||||
|
||||
if ( ci.isActiveParent() ) {
|
||||
|
||||
if ( (ci.name != null) && (ci.name != _("Planning")) ) {
|
||||
|
||||
breadcrumbsPath.add(ci);
|
||||
|
||||
for (CustomMenuItem child : ci.children) {
|
||||
|
||||
if ( child.isActiveParent() ) {
|
||||
|
||||
breadcrumbsPath.add(child);
|
||||
|
||||
for (CustomMenuItem c : child.children) {
|
||||
|
||||
if ( c.isActiveParent() ) {
|
||||
breadcrumbsPath.add(c);
|
||||
}
|
||||
|
|
@ -572,23 +609,28 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return breadcrumbsPath;
|
||||
}
|
||||
|
||||
public String getHelpLink() {
|
||||
String helpLink = "index.html";
|
||||
for (CustomMenuItem ci : this.firstLevel) {
|
||||
|
||||
if ( ci.isActiveParent() ) {
|
||||
|
||||
if ( (ci.name != null) ) {
|
||||
|
||||
for (CustomMenuItem child : ci.children) {
|
||||
if (child.isActiveParent()
|
||||
&& !child.helpLink.equals("")) {
|
||||
|
||||
if ( child.isActiveParent() && !child.helpLink.equals("") ) {
|
||||
helpLink = child.helpLink;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return helpLink;
|
||||
}
|
||||
|
||||
|
|
@ -598,27 +640,29 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
return ci.getChildren();
|
||||
}
|
||||
}
|
||||
return Collections.<CustomMenuItem> emptyList();
|
||||
|
||||
return Collections.emptyList();
|
||||
|
||||
}
|
||||
|
||||
private Button currentOne = null;
|
||||
|
||||
@Override
|
||||
public Object addMenuItem(String name, String cssClass,
|
||||
org.zkoss.zk.ui.event.EventListener eventListener) {
|
||||
public Object addMenuItem(String name, String cssClass, org.zkoss.zk.ui.event.EventListener eventListener) {
|
||||
Vbox insertionPoint = getRegisteredItemsInsertionPoint();
|
||||
Button button = new Button();
|
||||
button.setLabel(_(name));
|
||||
|
||||
if ( cssClass != null ) {
|
||||
toggleDomainCssClass(cssClass, button);
|
||||
}
|
||||
|
||||
setDeselectedClass(button);
|
||||
button.addEventListener(Events.ON_CLICK, doNotCallTwice(button,
|
||||
eventListener));
|
||||
button.addEventListener(Events.ON_CLICK, doNotCallTwice(button, eventListener));
|
||||
button.setMold("trendy");
|
||||
insertionPoint.appendChild(button);
|
||||
insertionPoint.appendChild(separator());
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
|
@ -631,20 +675,22 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
public void renameMenuItem(Object key, String name, String cssClass) {
|
||||
Button button = (Button) key;
|
||||
button.setLabel(name);
|
||||
|
||||
if ( cssClass != null ) {
|
||||
toggleDomainCssClass(cssClass, button);
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleDomainCssClass(String cssClass, Button button) {
|
||||
Matcher matcher = perspectiveCssClass
|
||||
.matcher(button.getSclass() == null ? "" : button.getSclass());
|
||||
Matcher matcher = perspectiveCssClass.matcher(button.getSclass() == null ? "" : button.getSclass());
|
||||
String previousPerspectiveClass;
|
||||
|
||||
if ( matcher.find() ) {
|
||||
previousPerspectiveClass = matcher.group();
|
||||
} else {
|
||||
previousPerspectiveClass = "";
|
||||
}
|
||||
|
||||
button.setSclass(previousPerspectiveClass + " " + cssClass);
|
||||
}
|
||||
|
||||
|
|
@ -663,23 +709,19 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
togglePerspectiveClassTo(button, "perspective");
|
||||
}
|
||||
|
||||
private static final Pattern perspectiveCssClass = Pattern
|
||||
.compile("\\bperspective(-\\w+)?\\b");
|
||||
private static final Pattern perspectiveCssClass = Pattern.compile("\\bperspective(-\\w+)?\\b");
|
||||
|
||||
private void togglePerspectiveClassTo(final Button button,
|
||||
String newPerspectiveClass) {
|
||||
button
|
||||
.setSclass(togglePerspectiveCssClass(newPerspectiveClass,
|
||||
button));
|
||||
private void togglePerspectiveClassTo(final Button button, String newPerspectiveClass) {
|
||||
button.setSclass(togglePerspectiveCssClass(newPerspectiveClass, button));
|
||||
}
|
||||
|
||||
private String togglePerspectiveCssClass(String newPerspectiveClass,
|
||||
Button button) {
|
||||
private String togglePerspectiveCssClass(String newPerspectiveClass, Button button) {
|
||||
String sclass = button.getSclass();
|
||||
if ( !perspectiveCssClass.matcher(sclass).find() ) {
|
||||
return newPerspectiveClass + " " + sclass;
|
||||
} else {
|
||||
Matcher matcher = perspectiveCssClass.matcher(sclass);
|
||||
|
||||
return matcher.replaceAll(newPerspectiveClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -693,6 +735,7 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
if ( currentOne == button ) {
|
||||
return;
|
||||
}
|
||||
|
||||
switchCurrentButtonTo(button);
|
||||
originalListener.onEvent(event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,16 +131,16 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
|
||||
private LimitingResourceQueueElement beingEdited;
|
||||
|
||||
private Set<LimitingResourceQueueElement> toBeRemoved = new HashSet<LimitingResourceQueueElement>();
|
||||
private Set<LimitingResourceQueueElement> toBeRemoved = new HashSet<>();
|
||||
|
||||
private Set<LimitingResourceQueueElement> toBeSaved = new HashSet<LimitingResourceQueueElement>();
|
||||
private Set<LimitingResourceQueueElement> toBeSaved = new HashSet<>();
|
||||
|
||||
private Set<TaskElement> parentElementsToBeUpdated = new HashSet<TaskElement>();
|
||||
private Set<TaskElement> parentElementsToBeUpdated = new HashSet<>();
|
||||
|
||||
private Scenario master;
|
||||
|
||||
private Map<LimitingResourceQueueElement, HashSet<LimitingResourceQueueDependency>> toBeSavedDependencies =
|
||||
new HashMap<LimitingResourceQueueElement, HashSet<LimitingResourceQueueDependency>>();
|
||||
new HashMap<>();
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
|
|
@ -155,21 +155,18 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
List<LimitingResourceQueue> queues = loadLimitingResourceQueues();
|
||||
queuesState = new QueuesState(queues, unassigned);
|
||||
final Date startingDate = getEarliestDate();
|
||||
Date endDate = (new LocalDate(startingDate)).plusYears(2)
|
||||
.toDateTimeAtCurrentTime().toDate();
|
||||
Date endDate = (new LocalDate(startingDate)).plusYears(2).toDateTimeAtCurrentTime().toDate();
|
||||
viewInterval = new Interval(startingDate, endDate);
|
||||
|
||||
Date currentDate = new Date();
|
||||
viewInterval = new Interval(
|
||||
startingDate.after(currentDate) ? currentDate : startingDate,
|
||||
endDate);
|
||||
viewInterval = new Interval(startingDate.after(currentDate) ? currentDate : startingDate, endDate);
|
||||
|
||||
}
|
||||
|
||||
private Date getEarliestDate() {
|
||||
final LimitingResourceQueueElement element = getEarliestQueueElement();
|
||||
return (element != null) ? element.getStartDate()
|
||||
.toDateTimeAtCurrentTime().toDate() : new Date();
|
||||
|
||||
return (element != null) ? element.getStartDate().toDateTimeAtCurrentTime().toDate() : new Date();
|
||||
}
|
||||
|
||||
private LimitingResourceQueueElement getEarliestQueueElement() {
|
||||
|
|
@ -180,26 +177,24 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
if ( element == null ) {
|
||||
continue;
|
||||
}
|
||||
if (earliestQueueElement == null
|
||||
|| isEarlier(element, earliestQueueElement)) {
|
||||
|
||||
if ( earliestQueueElement == null || isEarlier(element, earliestQueueElement) ) {
|
||||
earliestQueueElement = element;
|
||||
}
|
||||
}
|
||||
|
||||
return earliestQueueElement;
|
||||
}
|
||||
|
||||
private boolean isEarlier(LimitingResourceQueueElement arg1,
|
||||
LimitingResourceQueueElement arg2) {
|
||||
private boolean isEarlier(LimitingResourceQueueElement arg1, LimitingResourceQueueElement arg2) {
|
||||
return (arg1.getStartDate().isBefore(arg2.getStartDate()));
|
||||
}
|
||||
|
||||
private LimitingResourceQueueElement getFirstLimitingResourceQueueElement(
|
||||
LimitingResourceQueue queue) {
|
||||
private LimitingResourceQueueElement getFirstLimitingResourceQueueElement(LimitingResourceQueue queue) {
|
||||
return getFirstChild(queue.getLimitingResourceQueueElements());
|
||||
}
|
||||
|
||||
private LimitingResourceQueueElement getFirstChild(
|
||||
SortedSet<LimitingResourceQueueElement> elements) {
|
||||
private LimitingResourceQueueElement getFirstChild(SortedSet<LimitingResourceQueueElement> elements) {
|
||||
return (elements.isEmpty()) ? null : elements.iterator().next();
|
||||
}
|
||||
|
||||
|
|
@ -209,22 +204,21 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
* @return
|
||||
*/
|
||||
private List<LimitingResourceQueueElement> findUnassignedLimitingResourceQueueElements() {
|
||||
return initializeLimitingResourceQueueElements(limitingResourceQueueElementDAO
|
||||
.getUnassigned());
|
||||
return initializeLimitingResourceQueueElements(limitingResourceQueueElementDAO.getUnassigned());
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueueElement> initializeLimitingResourceQueueElements(
|
||||
List<LimitingResourceQueueElement> elements) {
|
||||
|
||||
for (LimitingResourceQueueElement each : elements) {
|
||||
initializeLimitingResourceQueueElement(each);
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
private void initializeLimitingResourceQueueElement(
|
||||
LimitingResourceQueueElement element) {
|
||||
ResourceAllocation<?> resourceAllocation = element
|
||||
.getResourceAllocation();
|
||||
private void initializeLimitingResourceQueueElement(LimitingResourceQueueElement element) {
|
||||
ResourceAllocation<?> resourceAllocation = element.getResourceAllocation();
|
||||
resourceAllocation.switchToScenario(master);
|
||||
resourceAllocation = initializeResourceAllocationIfNecessary(resourceAllocation);
|
||||
element.setResourceAllocation(resourceAllocation);
|
||||
|
|
@ -234,14 +228,19 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
|
||||
private void initializeTask(Task task) {
|
||||
if ( hasResourceAllocation(task) ) {
|
||||
ResourceAllocation<?> resourceAllocation = initializeResourceAllocationIfNecessary(getResourceAllocation(task));
|
||||
|
||||
ResourceAllocation<?> resourceAllocation =
|
||||
initializeResourceAllocationIfNecessary(getResourceAllocation(task));
|
||||
|
||||
task.setResourceAllocation(resourceAllocation);
|
||||
}
|
||||
|
||||
Hibernate.initialize(task);
|
||||
|
||||
for (ResourceAllocation<?> each: task.getAllResourceAllocations()) {
|
||||
Hibernate.initialize(each);
|
||||
}
|
||||
|
||||
initializeDependencies(task);
|
||||
initializeTaskSource(task.getTaskSource());
|
||||
initializeRootOrder(task);
|
||||
|
|
@ -251,6 +250,7 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
for (Dependency each: task.getDependenciesWithThisOrigin()) {
|
||||
Hibernate.initialize(each.getDestination());
|
||||
}
|
||||
|
||||
for (Dependency each: task.getDependenciesWithThisDestination()) {
|
||||
Hibernate.initialize(each.getOrigin());
|
||||
}
|
||||
|
|
@ -272,11 +272,11 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
}
|
||||
|
||||
// FIXME: Needed to fetch order.name in QueueComponent.composeTooltiptext.
|
||||
// Try to replace it with a HQL query instead of iterating all the way up
|
||||
// through order
|
||||
// Try to replace it with a HQL query instead of iterating all the way up through order
|
||||
private void initializeRootOrder(Task task) {
|
||||
Hibernate.initialize(task.getOrderElement());
|
||||
OrderElement order = task.getOrderElement();
|
||||
|
||||
do {
|
||||
Hibernate.initialize(order.getParent());
|
||||
order = order.getParent();
|
||||
|
|
@ -313,18 +313,21 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
}
|
||||
}
|
||||
|
||||
private ResourceAllocation<?> initializeResourceAllocationIfNecessary(
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
private ResourceAllocation<?> initializeResourceAllocationIfNecessary(ResourceAllocation<?> resourceAllocation) {
|
||||
if ( resourceAllocation instanceof HibernateProxy ) {
|
||||
|
||||
resourceAllocation = (ResourceAllocation<?>) ((HibernateProxy) resourceAllocation)
|
||||
.getHibernateLazyInitializer().getImplementation();
|
||||
|
||||
if ( resourceAllocation instanceof GenericResourceAllocation ) {
|
||||
GenericResourceAllocation generic = (GenericResourceAllocation) resourceAllocation;
|
||||
initializeCriteria(generic.getCriterions());
|
||||
}
|
||||
|
||||
Hibernate.initialize(resourceAllocation.getAssignments());
|
||||
Hibernate.initialize(resourceAllocation.getLimitingResourceQueueElement());
|
||||
}
|
||||
|
||||
return resourceAllocation;
|
||||
}
|
||||
|
||||
|
|
@ -340,22 +343,20 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
}
|
||||
|
||||
private List<LimitingResourceQueue> loadLimitingResourceQueues() {
|
||||
return initializeLimitingResourceQueues(limitingResourceQueueDAO
|
||||
.getAll());
|
||||
return initializeLimitingResourceQueues(limitingResourceQueueDAO.getAll());
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueue> initializeLimitingResourceQueues(
|
||||
List<LimitingResourceQueue> queues) {
|
||||
private List<LimitingResourceQueue> initializeLimitingResourceQueues(List<LimitingResourceQueue> queues) {
|
||||
for (LimitingResourceQueue each : queues) {
|
||||
initializeLimitingResourceQueue(each);
|
||||
}
|
||||
|
||||
return queues;
|
||||
}
|
||||
|
||||
private void initializeLimitingResourceQueue(LimitingResourceQueue queue) {
|
||||
initializeResourceIfAny(queue.getResource());
|
||||
for (LimitingResourceQueueElement each : queue
|
||||
.getLimitingResourceQueueElements()) {
|
||||
for (LimitingResourceQueueElement each : queue.getLimitingResourceQueueElements()) {
|
||||
initializeLimitingResourceQueueElement(each);
|
||||
}
|
||||
}
|
||||
|
|
@ -365,8 +366,8 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
Hibernate.initialize(resource);
|
||||
initializeCalendarIfAny(resource.getCalendar());
|
||||
resource.getAssignments();
|
||||
for (CriterionSatisfaction each : resource
|
||||
.getCriterionSatisfactions()) {
|
||||
|
||||
for (CriterionSatisfaction each : resource.getCriterionSatisfactions()) {
|
||||
Hibernate.initialize(each);
|
||||
initializeCriterion(each.getCriterion());
|
||||
}
|
||||
|
|
@ -390,22 +391,25 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
if ( SecurityUtils.isSuperuserOrUserInRoles(
|
||||
UserRole.ROLE_READ_ALL_PROJECTS,
|
||||
UserRole.ROLE_EDIT_ALL_PROJECTS)) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
User user = userDAO.findByLoginName(loginName);
|
||||
for (OrderAuthorization authorization : orderAuthorizationDAO
|
||||
.listByOrderUserAndItsProfiles(order, user)) {
|
||||
if (authorization.getAuthorizationType() == OrderAuthorizationType.READ_AUTHORIZATION
|
||||
|| authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION) {
|
||||
for (OrderAuthorization authorization : orderAuthorizationDAO.listByOrderUserAndItsProfiles(order, user)) {
|
||||
|
||||
if ( authorization.getAuthorizationType() == OrderAuthorizationType.READ_AUTHORIZATION ||
|
||||
authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (InstanceNotFoundException e) {
|
||||
// this case shouldn't happen, because it would mean that there
|
||||
// isn't a logged user
|
||||
// anyway, if it happenned we don't allow the user to pass
|
||||
// anyway, if it happened we don't allow the user to pass
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -422,30 +426,31 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
@Override
|
||||
public ZoomLevel calculateInitialZoomLevel() {
|
||||
Interval interval = getViewInterval();
|
||||
return ZoomLevel.getDefaultZoomByDates(new LocalDate(interval
|
||||
.getStart()), new LocalDate(interval.getFinish()));
|
||||
return ZoomLevel.getDefaultZoomByDates(new LocalDate(interval.getStart()), new LocalDate(interval.getFinish()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LimitingResourceQueueElement> assignLimitingResourceQueueElement(
|
||||
LimitingResourceQueueElement externalQueueElement) {
|
||||
|
||||
InsertionRequirements requirements = queuesState
|
||||
.getRequirementsFor(externalQueueElement);
|
||||
InsertionRequirements requirements = queuesState.getRequirementsFor(externalQueueElement);
|
||||
AllocationSpec allocation = insertAtGap(requirements);
|
||||
|
||||
if ( allocation == null ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
applyAllocation(allocation);
|
||||
|
||||
assert allocation.isValid();
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
result.add(requirements.getElement());
|
||||
|
||||
List<LimitingResourceQueueElement> moved = shift(
|
||||
queuesState
|
||||
.getPotentiallyAffectedByInsertion(externalQueueElement),
|
||||
requirements.getElement(), allocation);
|
||||
queuesState.getPotentiallyAffectedByInsertion(externalQueueElement),
|
||||
requirements.getElement(),
|
||||
allocation);
|
||||
|
||||
result.addAll(rescheduleAffectedElementsToSatisfyDependencies(allocation, moved));
|
||||
|
||||
return result;
|
||||
|
|
@ -466,8 +471,8 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
private Collection<? extends LimitingResourceQueueElement> rescheduleAffectedElementsToSatisfyDependencies(
|
||||
AllocationSpec allocation, List<LimitingResourceQueueElement> moved) {
|
||||
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
List<LimitingResourceQueueElement> toReschedule = new ArrayList<LimitingResourceQueueElement>();
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
List<LimitingResourceQueueElement> toReschedule = new ArrayList<>();
|
||||
|
||||
checkAllocationIsAppropriative(false);
|
||||
for (LimitingResourceQueueElement each: moved) {
|
||||
|
|
@ -476,9 +481,11 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
if ( allocation.isAppropriative() ) {
|
||||
toReschedule.addAll(allocation.getUnscheduledElements());
|
||||
}
|
||||
|
||||
for (LimitingResourceQueueElement each: queuesState.inTopologicalOrder(toReschedule)) {
|
||||
result.addAll(assignLimitingResourceQueueElement(each));
|
||||
}
|
||||
|
||||
checkAllocationIsAppropriative(true);
|
||||
|
||||
return result;
|
||||
|
|
@ -498,9 +505,11 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
AllocationSpec allocationAlreadyDone) {
|
||||
|
||||
List<AllocationSpec> allocationsToBeDone = getAllocationsToBeDone(
|
||||
potentiallyAffectedByInsertion, elementInserted,
|
||||
potentiallyAffectedByInsertion,
|
||||
elementInserted,
|
||||
allocationAlreadyDone);
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
for (AllocationSpec each : allocationsToBeDone) {
|
||||
applyAllocation(each);
|
||||
|
||||
|
|
@ -515,31 +524,36 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
DirectedGraph<LimitingResourceQueueElement, Edge> potentiallyAffectedByInsertion,
|
||||
LimitingResourceQueueElement elementInserted,
|
||||
AllocationSpec allocationAlreadyDone) {
|
||||
List<AllocationSpec> result = new ArrayList<AllocationSpec>();
|
||||
Map<LimitingResourceQueueElement, AllocationSpec> allocationsToBeDoneByElement = new HashMap<LimitingResourceQueueElement, AllocationSpec>();
|
||||
|
||||
List<AllocationSpec> result = new ArrayList<>();
|
||||
Map<LimitingResourceQueueElement, AllocationSpec> allocationsToBeDoneByElement = new HashMap<>();
|
||||
allocationsToBeDoneByElement.put(elementInserted, allocationAlreadyDone);
|
||||
|
||||
List<LimitingResourceQueueElement> mightNeedShift = withoutElementInserted(
|
||||
elementInserted,
|
||||
QueuesState.topologicalIterator(potentiallyAffectedByInsertion));
|
||||
|
||||
for (LimitingResourceQueueElement each : mightNeedShift) {
|
||||
AllocationSpec futureAllocation = getAllocationToBeDoneFor(
|
||||
potentiallyAffectedByInsertion,
|
||||
allocationsToBeDoneByElement, each);
|
||||
|
||||
AllocationSpec futureAllocation =
|
||||
getAllocationToBeDoneFor(potentiallyAffectedByInsertion, allocationsToBeDoneByElement, each);
|
||||
|
||||
if ( futureAllocation != null ) {
|
||||
result.add(futureAllocation);
|
||||
allocationsToBeDoneByElement.put(each, futureAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueueElement> withoutElementInserted(
|
||||
LimitingResourceQueueElement elementInserted,
|
||||
final TopologicalOrderIterator<LimitingResourceQueueElement, Edge> topologicalIterator) {
|
||||
List<LimitingResourceQueueElement> result = QueuesState
|
||||
.toList(topologicalIterator);
|
||||
|
||||
List<LimitingResourceQueueElement> result = QueuesState.toList(topologicalIterator);
|
||||
result.remove(elementInserted);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -547,53 +561,50 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
DirectedGraph<LimitingResourceQueueElement, Edge> potentiallyAffectedByInsertion,
|
||||
Map<LimitingResourceQueueElement, AllocationSpec> allocationsToBeDoneByElement,
|
||||
LimitingResourceQueueElement current) {
|
||||
|
||||
Validate.isTrue(!current.isDetached());
|
||||
DateAndHour newStart = current.getStartTime();
|
||||
DateAndHour newEnd = current.getEndTime();
|
||||
Map<LimitingResourceQueueElement, List<Edge>> incoming = bySource(potentiallyAffectedByInsertion
|
||||
.incomingEdgesOf(current));
|
||||
for (Entry<LimitingResourceQueueElement, List<Edge>> each : incoming
|
||||
.entrySet()) {
|
||||
AllocationSpec previous = allocationsToBeDoneByElement.get(each
|
||||
.getKey());
|
||||
|
||||
Map<LimitingResourceQueueElement, List<Edge>> incoming =
|
||||
bySource(potentiallyAffectedByInsertion.incomingEdgesOf(current));
|
||||
|
||||
for (Entry<LimitingResourceQueueElement, List<Edge>> each : incoming.entrySet()) {
|
||||
AllocationSpec previous = allocationsToBeDoneByElement.get(each.getKey());
|
||||
if ( previous != null ) {
|
||||
newStart = DateAndHour.max(newStart, getStartFrom(previous,
|
||||
each.getValue()));
|
||||
newEnd = DateAndHour.max(newEnd, getEndFrom(previous, each
|
||||
.getValue()));
|
||||
newStart = DateAndHour.max(newStart, getStartFrom(previous, each.getValue()));
|
||||
newEnd = DateAndHour.max(newEnd, getEndFrom(previous, each.getValue()));
|
||||
}
|
||||
}
|
||||
if (current.getStartTime().compareTo(newStart) == 0
|
||||
&& current.getEndTime().compareTo(newEnd) == 0) {
|
||||
|
||||
if (current.getStartTime().compareTo(newStart) == 0 && current.getEndTime().compareTo(newEnd) == 0) {
|
||||
return null;
|
||||
}
|
||||
InsertionRequirements requirements = InsertionRequirements.create(
|
||||
current, newStart, newEnd);
|
||||
GapOnQueue gap = Gap.untilEnd(current, newStart).onQueue(
|
||||
current.getLimitingResourceQueue());
|
||||
|
||||
InsertionRequirements requirements = InsertionRequirements.create(current, newStart, newEnd);
|
||||
GapOnQueue gap = Gap.untilEnd(current, newStart).onQueue(current.getLimitingResourceQueue());
|
||||
AllocationSpec result = requirements.guessValidity(gap);
|
||||
assert result.isValid();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private DateAndHour getStartFrom(AllocationSpec previous,
|
||||
List<Edge> edges) {
|
||||
private DateAndHour getStartFrom(AllocationSpec previous, List<Edge> edges) {
|
||||
DateAndHour result = null;
|
||||
for (Edge each : edges) {
|
||||
result = DateAndHour.max(result,
|
||||
calculateStart(previous, each.type));
|
||||
result = DateAndHour.max(result, calculateStart(previous, each.type));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private DateAndHour calculateStart(AllocationSpec previous,
|
||||
QueueDependencyType type) {
|
||||
private DateAndHour calculateStart(AllocationSpec previous, QueueDependencyType type) {
|
||||
if ( !type.modifiesDestinationStart() ) {
|
||||
return null;
|
||||
}
|
||||
return type.calculateDateTargetFrom(previous.getStartInclusive(), previous
|
||||
.getEndExclusive());
|
||||
|
||||
return type.calculateDateTargetFrom(previous.getStartInclusive(), previous.getEndExclusive());
|
||||
}
|
||||
|
||||
private DateAndHour getEndFrom(AllocationSpec previous, List<Edge> edges) {
|
||||
|
|
@ -601,27 +612,29 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
for (Edge each : edges) {
|
||||
result = DateAndHour.max(result, calculateEnd(previous, each.type));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private DateAndHour calculateEnd(AllocationSpec previous,
|
||||
QueueDependencyType type) {
|
||||
private DateAndHour calculateEnd(AllocationSpec previous, QueueDependencyType type) {
|
||||
if ( !type.modifiesDestinationEnd() ) {
|
||||
return null;
|
||||
}
|
||||
return type.calculateDateTargetFrom(previous.getStartInclusive(),
|
||||
previous.getEndExclusive());
|
||||
|
||||
return type.calculateDateTargetFrom(previous.getStartInclusive(), previous.getEndExclusive());
|
||||
}
|
||||
|
||||
private Map<LimitingResourceQueueElement, List<Edge>> bySource(
|
||||
Collection<? extends Edge> incomingEdgesOf) {
|
||||
Map<LimitingResourceQueueElement, List<Edge>> result = new HashMap<LimitingResourceQueueElement, List<Edge>>();
|
||||
private Map<LimitingResourceQueueElement, List<Edge>> bySource(Collection<? extends Edge> incomingEdgesOf) {
|
||||
Map<LimitingResourceQueueElement, List<Edge>> result = new HashMap<>();
|
||||
for (Edge each : incomingEdgesOf) {
|
||||
|
||||
if ( result.get(each.source) == null ) {
|
||||
result.put(each.source, new ArrayList<Edge>());
|
||||
}
|
||||
|
||||
result.get(each.source).add(each);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -631,6 +644,7 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
*/
|
||||
private AllocationSpec insertAtGap(InsertionRequirements requirements) {
|
||||
AllocationSpec allocationStillNotDone = findAllocationSpecFor(requirements);
|
||||
|
||||
return doAppropriativeIfNecessary(allocationStillNotDone, requirements);
|
||||
}
|
||||
|
||||
|
|
@ -641,69 +655,72 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
* @return
|
||||
*/
|
||||
private AllocationSpec findAllocationSpecFor(InsertionRequirements requirements) {
|
||||
List<GapOnQueue> potentiallyValidGapsFor = queuesState
|
||||
.getPotentiallyValidGapsFor(requirements);
|
||||
List<GapOnQueue> potentiallyValidGapsFor = queuesState.getPotentiallyValidGapsFor(requirements);
|
||||
|
||||
return findAllocationSpecFor(potentiallyValidGapsFor, requirements);
|
||||
}
|
||||
|
||||
private AllocationSpec findAllocationSpecFor(List<GapOnQueue> gapsOnQueue, InsertionRequirements requirements) {
|
||||
boolean generic = requirements.getElement().isGeneric();
|
||||
for (GapOnQueue each : gapsOnQueue) {
|
||||
for (GapOnQueue eachSubGap : getSubGaps(each,
|
||||
requirements.getElement(), generic)) {
|
||||
AllocationSpec allocation = requirements
|
||||
.guessValidity(eachSubGap);
|
||||
|
||||
for (GapOnQueue eachSubGap : getSubGaps(each, requirements.getElement(), generic)) {
|
||||
|
||||
AllocationSpec allocation = requirements.guessValidity(eachSubGap);
|
||||
|
||||
if ( allocation.isValid() ) {
|
||||
return allocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private AllocationSpec doAppropriativeIfNecessary(AllocationSpec allocation,
|
||||
InsertionRequirements requirements) {
|
||||
private AllocationSpec doAppropriativeIfNecessary(AllocationSpec allocation, InsertionRequirements requirements) {
|
||||
if ( allocation != null ) {
|
||||
if (checkAllocationIsAppropriative()
|
||||
&& requirements.isAppropiativeAllocation(allocation)) {
|
||||
if ( checkAllocationIsAppropriative() && requirements.isAppropiativeAllocation(allocation) ) {
|
||||
return doAppropriativeAllocation(requirements, allocation);
|
||||
}
|
||||
|
||||
return allocation;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private AllocationSpec insertAtGap(InsertionRequirements requirements, LimitingResourceQueue queue) {
|
||||
AllocationSpec allocationStillNotDone = findAllocationSpecForInQueue(requirements, queue);
|
||||
|
||||
return doAppropriativeIfNecessary(allocationStillNotDone, requirements);
|
||||
}
|
||||
|
||||
private AllocationSpec findAllocationSpecForInQueue(
|
||||
InsertionRequirements requirements, LimitingResourceQueue queue) {
|
||||
private AllocationSpec findAllocationSpecForInQueue(InsertionRequirements requirements,
|
||||
LimitingResourceQueue queue) {
|
||||
|
||||
List<GapOnQueue> potentiallyValidGapsFor = new ArrayList<GapOnQueue>();
|
||||
List<GapOnQueue> potentiallyValidGapsFor = new ArrayList<>();
|
||||
|
||||
for (GapOnQueue each : queuesState
|
||||
.getPotentiallyValidGapsFor(requirements)) {
|
||||
for (GapOnQueue each : queuesState.getPotentiallyValidGapsFor(requirements)) {
|
||||
if ( each.getOriginQueue().equals(queue) ) {
|
||||
potentiallyValidGapsFor.add(each);
|
||||
}
|
||||
}
|
||||
|
||||
return findAllocationSpecFor(potentiallyValidGapsFor, requirements);
|
||||
}
|
||||
|
||||
private boolean checkAllocationIsAppropriative = true;
|
||||
|
||||
private AllocationSpec doAppropriativeAllocation(
|
||||
InsertionRequirements requirements, AllocationSpec allocation) {
|
||||
private AllocationSpec doAppropriativeAllocation(InsertionRequirements requirements, AllocationSpec allocation) {
|
||||
|
||||
LimitingResourceQueueElement element = requirements.getElement();
|
||||
List<LimitingResourceQueue> potentiallyValidQueues = getAssignableQueues(element);
|
||||
LimitingResourceQueue queue = earliestQueue(potentiallyValidQueues);
|
||||
|
||||
List<LimitingResourceQueueElement> unscheduled = new ArrayList<LimitingResourceQueueElement>();
|
||||
List<LimitingResourceQueueElement> unscheduled = new ArrayList<>();
|
||||
allocation = unscheduleElementsFor(queue, requirements, unscheduled);
|
||||
allocation.setUnscheduledElements(queuesState.inTopologicalOrder(unscheduled));
|
||||
|
||||
return allocation;
|
||||
}
|
||||
|
||||
|
|
@ -713,26 +730,28 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
* @param potentiallyValidQueues
|
||||
* @return
|
||||
*/
|
||||
private LimitingResourceQueue earliestQueue(
|
||||
List<LimitingResourceQueue> potentiallyValidQueues) {
|
||||
private LimitingResourceQueue earliestQueue(List<LimitingResourceQueue> potentiallyValidQueues) {
|
||||
|
||||
LimitingResourceQueue result = null;
|
||||
LocalDate latestDate = null;
|
||||
|
||||
for (LimitingResourceQueue each : potentiallyValidQueues) {
|
||||
SortedSet<LimitingResourceQueueElement> elements = each
|
||||
.getLimitingResourceQueueElements();
|
||||
SortedSet<LimitingResourceQueueElement> elements = each.getLimitingResourceQueueElements();
|
||||
|
||||
if ( !elements.isEmpty() ) {
|
||||
LocalDate date = elements.last().getEndDate();
|
||||
|
||||
if ( latestDate == null || date.isAfter(latestDate) ) {
|
||||
latestDate = date;
|
||||
result = each;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( result == null && !potentiallyValidQueues.isEmpty() ) {
|
||||
result = potentiallyValidQueues.get(0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -744,11 +763,11 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
return checkAllocationIsAppropriative;
|
||||
}
|
||||
|
||||
private List<GapOnQueue> getSubGaps(GapOnQueue each,
|
||||
LimitingResourceQueueElement element, boolean generic) {
|
||||
private List<GapOnQueue> getSubGaps(GapOnQueue each, LimitingResourceQueueElement element, boolean generic) {
|
||||
if ( generic ) {
|
||||
return each.splitIntoGapsSatisfyingCriteria(element.getCriteria());
|
||||
}
|
||||
|
||||
return Collections.singletonList(each);
|
||||
}
|
||||
|
||||
|
|
@ -756,15 +775,14 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
applyAllocation(allocationStillNotDone, new IDayAssignmentBehaviour() {
|
||||
|
||||
@Override
|
||||
public void allocateDayAssigments(IntraDayDate start,
|
||||
IntraDayDate end) {
|
||||
public void allocateDayAssigments(IntraDayDate start, IntraDayDate end) {
|
||||
ResourceAllocation<?> resourceAllocation = getResourceAllocation(allocationStillNotDone);
|
||||
Resource resource = getResource(allocationStillNotDone);
|
||||
|
||||
List<DayAssignment> assignments = allocationStillNotDone.getAssignmentsFor(
|
||||
resourceAllocation, resource);
|
||||
resourceAllocation.allocateLimitingDayAssignments(assignments,
|
||||
start, end);
|
||||
List<DayAssignment> assignments =
|
||||
allocationStillNotDone.getAssignmentsFor(resourceAllocation, resource);
|
||||
|
||||
resourceAllocation.allocateLimitingDayAssignments(assignments, start, end);
|
||||
}
|
||||
|
||||
private ResourceAllocation<?> getResourceAllocation(AllocationSpec allocation) {
|
||||
|
|
@ -776,35 +794,33 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
}
|
||||
|
||||
});
|
||||
|
||||
return allocationStillNotDone;
|
||||
}
|
||||
|
||||
private void applyAllocation(AllocationSpec allocationStillNotDone,
|
||||
IDayAssignmentBehaviour allocationBehaviour) {
|
||||
private void applyAllocation(AllocationSpec allocationStillNotDone, IDayAssignmentBehaviour allocationBehaviour) {
|
||||
|
||||
// Do day allocation
|
||||
allocationBehaviour.allocateDayAssigments(
|
||||
convert(allocationStillNotDone.getStartInclusive()),
|
||||
convert(allocationStillNotDone.getEndExclusive()));
|
||||
|
||||
LimitingResourceQueueElement element = allocationStillNotDone
|
||||
.getElement();
|
||||
LimitingResourceQueueElement element = allocationStillNotDone.getElement();
|
||||
LimitingResourceQueue queue = allocationStillNotDone.getQueue();
|
||||
|
||||
// Update start and end time of task
|
||||
updateStartAndEndTimes(element, allocationStillNotDone
|
||||
.getStartInclusive(), allocationStillNotDone
|
||||
.getEndExclusive());
|
||||
updateStartAndEndTimes(
|
||||
element,
|
||||
allocationStillNotDone.getStartInclusive(),
|
||||
allocationStillNotDone.getEndExclusive());
|
||||
|
||||
// Add to queue and mark as modified
|
||||
addLimitingResourceQueueElementIfNeeded(queue, element);
|
||||
markAsModified(element);
|
||||
}
|
||||
|
||||
private DateAndHour getEndsAfterBecauseOfGantt(
|
||||
LimitingResourceQueueElement queueElement) {
|
||||
return DateAndHour.from(LocalDate.fromDateFields(queueElement
|
||||
.getEarliestEndDateBecauseOfGantt()));
|
||||
private DateAndHour getEndsAfterBecauseOfGantt(LimitingResourceQueueElement queueElement) {
|
||||
return DateAndHour.from(LocalDate.fromDateFields(queueElement.getEarliestEndDateBecauseOfGantt()));
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueueElement> assignLimitingResourceQueueElementToQueueAt(
|
||||
|
|
@ -814,9 +830,9 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
final DateAndHour endsAfter) {
|
||||
|
||||
// Check if allocation is possible
|
||||
InsertionRequirements requirements = queuesState.getRequirementsFor(
|
||||
element, startAt);
|
||||
InsertionRequirements requirements = queuesState.getRequirementsFor(element, startAt);
|
||||
AllocationSpec allocation = insertAtGap(requirements, queue);
|
||||
|
||||
if ( !allocation.isValid() ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
@ -825,15 +841,13 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
applyAllocation(allocation, new IDayAssignmentBehaviour() {
|
||||
|
||||
@Override
|
||||
public void allocateDayAssigments(IntraDayDate start,
|
||||
IntraDayDate end) {
|
||||
public void allocateDayAssigments(IntraDayDate start, IntraDayDate end) {
|
||||
|
||||
List<DayAssignment> assignments = LimitingResourceAllocator
|
||||
.generateDayAssignments(
|
||||
List<DayAssignment> assignments = LimitingResourceAllocator.generateDayAssignments(
|
||||
element.getResourceAllocation(),
|
||||
queue.getResource(), startAt, endsAfter);
|
||||
element.getResourceAllocation().allocateLimitingDayAssignments(
|
||||
assignments, start, end);
|
||||
|
||||
element.getResourceAllocation().allocateLimitingDayAssignments(assignments, start, end);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -841,12 +855,13 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
assert allocation.isValid();
|
||||
|
||||
// Move other tasks to respect dependency constraints
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
result.add(requirements.getElement());
|
||||
|
||||
List<LimitingResourceQueueElement> moved = shift(
|
||||
queuesState.getPotentiallyAffectedByInsertion(element),
|
||||
requirements.getElement(), allocation);
|
||||
|
||||
result.addAll(rescheduleAffectedElementsToSatisfyDependencies(allocation, moved));
|
||||
|
||||
return result;
|
||||
|
|
@ -871,13 +886,13 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
}
|
||||
}
|
||||
|
||||
public Gap createGap(Resource resource, DateAndHour startTime,
|
||||
DateAndHour endTime) {
|
||||
public Gap createGap(Resource resource, DateAndHour startTime, DateAndHour endTime) {
|
||||
return Gap.create(resource, startTime, endTime);
|
||||
}
|
||||
|
||||
private void updateStartAndEndTimes(LimitingResourceQueueElement element,
|
||||
DateAndHour startTime, DateAndHour endTime) {
|
||||
DateAndHour startTime,
|
||||
DateAndHour endTime) {
|
||||
|
||||
element.setStartDate(startTime.getDate());
|
||||
element.setStartHour(startTime.getHour());
|
||||
|
|
@ -890,12 +905,10 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
}
|
||||
|
||||
private IntraDayDate convert(DateAndHour dateAndHour) {
|
||||
return IntraDayDate.create(dateAndHour.getDate(),
|
||||
EffortDuration.hours(dateAndHour.getHour()));
|
||||
return IntraDayDate.create(dateAndHour.getDate(), EffortDuration.hours(dateAndHour.getHour()));
|
||||
}
|
||||
|
||||
private void updateStartingAndEndingDate(Task task, IntraDayDate startDate,
|
||||
IntraDayDate endDate) {
|
||||
private void updateStartingAndEndingDate(Task task, IntraDayDate startDate, IntraDayDate endDate) {
|
||||
task.setIntraDayStartDate(startDate);
|
||||
task.setIntraDayEndDate(endDate);
|
||||
task.explicityMoved(startDate, endDate);
|
||||
|
|
@ -903,6 +916,7 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
|
||||
private void addLimitingResourceQueueElementIfNeeded(LimitingResourceQueue queue,
|
||||
LimitingResourceQueueElement element) {
|
||||
|
||||
if ( element.getLimitingResourceQueue() == null ) {
|
||||
queuesState.assignedToQueue(element, queue);
|
||||
}
|
||||
|
|
@ -931,14 +945,16 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
parentElementsToBeUpdated.clear();
|
||||
}
|
||||
|
||||
private List<ResourceAllocation<?>> getAllocations(
|
||||
Collection<? extends LimitingResourceQueueElement> elements) {
|
||||
List<ResourceAllocation<?>> result = new ArrayList<ResourceAllocation<?>>();
|
||||
private List<ResourceAllocation<?>> getAllocations(Collection<? extends LimitingResourceQueueElement> elements) {
|
||||
List<ResourceAllocation<?>> result = new ArrayList<>();
|
||||
|
||||
for (LimitingResourceQueueElement each : elements) {
|
||||
|
||||
if ( each.getResourceAllocation() != null ) {
|
||||
result.add(each.getResourceAllocation());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -946,24 +962,30 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
Long previousId = element.getId();
|
||||
limitingResourceQueueElementDAO.save(element);
|
||||
limitingResourceQueueDAO.flush();
|
||||
|
||||
if ( element.isNewObject() ) {
|
||||
queuesState.idChangedFor(previousId, element);
|
||||
}
|
||||
|
||||
element.dontPoseAsTransientObjectAnymore();
|
||||
element.getResourceAllocation().dontPoseAsTransientObjectAnymore();
|
||||
|
||||
for (DayAssignment each: element.getDayAssignments()) {
|
||||
each.dontPoseAsTransientObjectAnymore();
|
||||
}
|
||||
|
||||
if ( toBeSavedDependencies.get(element) != null ) {
|
||||
saveDependencies(toBeSavedDependencies.get(element));
|
||||
toBeSavedDependencies.remove(element);
|
||||
}
|
||||
|
||||
taskDAO.save(getAssociatedTask(element));
|
||||
}
|
||||
|
||||
private void updateEndDateForParentTasks() {
|
||||
for(TaskElement task : parentElementsToBeUpdated) {
|
||||
TaskElement parent = task;
|
||||
|
||||
while(parent != null) {
|
||||
parent.setIntraDayEndDate(null);
|
||||
parent.initializeDatesIfNeeded();
|
||||
|
|
@ -988,6 +1010,7 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
for (LimitingResourceQueueElement each: toBeRemoved) {
|
||||
removeQueueElement(each);
|
||||
}
|
||||
|
||||
toBeRemoved.clear();
|
||||
}
|
||||
|
||||
|
|
@ -1010,6 +1033,7 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
for (Dependency each: task.getDependenciesWithThisOrigin()) {
|
||||
removeQueueDependencyIfAny(each);
|
||||
}
|
||||
|
||||
for (Dependency each: task.getDependenciesWithThisDestination()) {
|
||||
removeQueueDependencyIfAny(each);
|
||||
}
|
||||
|
|
@ -1055,13 +1079,11 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
*
|
||||
*/
|
||||
@Override
|
||||
public void removeUnassignedLimitingResourceQueueElement(
|
||||
LimitingResourceQueueElement element) {
|
||||
public void removeUnassignedLimitingResourceQueueElement(LimitingResourceQueueElement element) {
|
||||
LimitingResourceQueueElement queueElement = queuesState.getEquivalent(element);
|
||||
|
||||
queueElement.getResourceAllocation().setLimitingResourceQueueElement(null);
|
||||
queueElement.getResourceAllocation().getTask()
|
||||
.removeAllResourceAllocations();
|
||||
queueElement.getResourceAllocation().getTask().removeAllResourceAllocations();
|
||||
queuesState.removeUnassigned(queueElement);
|
||||
markAsRemoved(queueElement);
|
||||
}
|
||||
|
|
@ -1070,14 +1092,14 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
if ( toBeSaved.contains(element) ) {
|
||||
toBeSaved.remove(element);
|
||||
}
|
||||
|
||||
if ( !toBeRemoved.contains(element) ) {
|
||||
toBeRemoved.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LimitingResourceQueue> getAssignableQueues(
|
||||
LimitingResourceQueueElement element) {
|
||||
public List<LimitingResourceQueue> getAssignableQueues(LimitingResourceQueueElement element) {
|
||||
return queuesState.getAssignableQueues(element);
|
||||
}
|
||||
|
||||
|
|
@ -1094,8 +1116,12 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
if ( element.getLimitingResourceQueue() != null ) {
|
||||
unschedule(element);
|
||||
}
|
||||
return assignLimitingResourceQueueElementToQueueAt(element, queue,
|
||||
startTime, getEndsAfterBecauseOfGantt(element));
|
||||
|
||||
return assignLimitingResourceQueueElementToQueueAt(
|
||||
element,
|
||||
queue,
|
||||
startTime,
|
||||
getEndsAfterBecauseOfGantt(element));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1113,30 +1139,31 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
LimitingResourceQueueElement _element,
|
||||
LimitingResourceQueue _queue, DateAndHour allocationTime) {
|
||||
|
||||
Set<LimitingResourceQueueElement> result = new HashSet<LimitingResourceQueueElement>();
|
||||
Set<LimitingResourceQueueElement> result = new HashSet<>();
|
||||
|
||||
LimitingResourceQueue queue = queuesState.getEquivalent(_queue);
|
||||
LimitingResourceQueueElement element = queuesState.getEquivalent(_element);
|
||||
|
||||
InsertionRequirements requirements = queuesState
|
||||
.getRequirementsFor(element, allocationTime);
|
||||
InsertionRequirements requirements = queuesState.getRequirementsFor(element, allocationTime);
|
||||
|
||||
if ( element.getLimitingResourceQueue() != null ) {
|
||||
unschedule(element);
|
||||
}
|
||||
|
||||
// Unschedule elements in queue since allocationTime and put them in
|
||||
// toSchedule
|
||||
List<LimitingResourceQueueElement> toSchedule = new ArrayList<LimitingResourceQueueElement>();
|
||||
// Unschedule elements in queue since allocationTime and put them in toSchedule
|
||||
List<LimitingResourceQueueElement> toSchedule = new ArrayList<>();
|
||||
unscheduleElementsFor(queue, requirements, toSchedule);
|
||||
|
||||
result.addAll(assignLimitingResourceQueueElementToQueueAt(element,
|
||||
queue, allocationTime, getEndsAfterBecauseOfGantt(element)));
|
||||
result.addAll(assignLimitingResourceQueueElementToQueueAt(
|
||||
element,
|
||||
queue,
|
||||
allocationTime,
|
||||
getEndsAfterBecauseOfGantt(element)));
|
||||
|
||||
for (LimitingResourceQueueElement each: queuesState
|
||||
.inTopologicalOrder(toSchedule)) {
|
||||
for (LimitingResourceQueueElement each: queuesState.inTopologicalOrder(toSchedule)) {
|
||||
result.addAll(assignLimitingResourceQueueElement(each));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1156,9 +1183,10 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
private AllocationSpec unscheduleElementsFor(
|
||||
LimitingResourceQueue queue, InsertionRequirements requirements,
|
||||
List<LimitingResourceQueueElement> result) {
|
||||
|
||||
DateAndHour allocationTime = requirements.getEarliestPossibleStart();
|
||||
List<GapOnQueueWithQueueElement> gapsWithQueueElements = queuesState
|
||||
.getGapsWithQueueElementsOnQueueSince(queue, allocationTime);
|
||||
List<GapOnQueueWithQueueElement> gapsWithQueueElements =
|
||||
queuesState.getGapsWithQueueElementsOnQueueSince(queue, allocationTime);
|
||||
|
||||
return unscheduleElementsFor(gapsWithQueueElements, requirements, result);
|
||||
}
|
||||
|
|
@ -1170,19 +1198,24 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
if ( gaps.isEmpty() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
GapOnQueueWithQueueElement first = gaps.get(0);
|
||||
GapOnQueue gapOnQueue = first.getGapOnQueue();
|
||||
|
||||
if ( gapOnQueue != null ) {
|
||||
AllocationSpec allocation = requirements.guessValidity(gapOnQueue);
|
||||
if ( allocation.isValid() ) {
|
||||
return allocation;
|
||||
}
|
||||
}
|
||||
|
||||
result.add(unschedule(first.getQueueElement()));
|
||||
if ( gaps.size() > 1 ) {
|
||||
gaps.set(1, GapOnQueueWithQueueElement.coalesce(first, gaps.get(1)));
|
||||
}
|
||||
|
||||
gaps.remove(0);
|
||||
|
||||
return unscheduleElementsFor(gaps, requirements, result);
|
||||
}
|
||||
|
||||
|
|
@ -1192,6 +1225,7 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
|
||||
// First element
|
||||
final LimitingResourceQueueElement first = elements.get(0);
|
||||
|
||||
if ( isAfter(first, allocationTime) ) {
|
||||
return first;
|
||||
}
|
||||
|
|
@ -1199,11 +1233,12 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
// Rest of elements
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
final LimitingResourceQueueElement each = elements.get(i);
|
||||
if (isInTheMiddle(each, allocationTime) ||
|
||||
isAfter(each, allocationTime)) {
|
||||
|
||||
if ( isInTheMiddle(each, allocationTime) || isAfter(each, allocationTime) ) {
|
||||
return each;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -1213,7 +1248,7 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
LimitingResourceQueueElement oldElement,
|
||||
LimitingResourceQueueElement newElement) {
|
||||
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
|
||||
boolean needToReassign = oldElement.hasDayAssignments();
|
||||
|
||||
|
|
@ -1225,7 +1260,8 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
if ( needToReassign ) {
|
||||
result.addAll(assignLimitingResourceQueueElement(newElement));
|
||||
}
|
||||
HashSet<LimitingResourceQueueDependency> dependencies = new HashSet<LimitingResourceQueueDependency>();
|
||||
|
||||
HashSet<LimitingResourceQueueDependency> dependencies = new HashSet<>();
|
||||
dependencies.addAll(newElement.getDependenciesAsOrigin());
|
||||
dependencies.addAll(newElement.getDependenciesAsDestiny());
|
||||
toBeSavedDependencies.put(newElement, dependencies);
|
||||
|
|
@ -1239,10 +1275,12 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
|||
@Override
|
||||
public Set<LimitingResourceQueueElement> assignLimitingResourceQueueElements(
|
||||
List<LimitingResourceQueueElement> queueElements) {
|
||||
Set<LimitingResourceQueueElement> result = new HashSet<LimitingResourceQueueElement>();
|
||||
|
||||
Set<LimitingResourceQueueElement> result = new HashSet<>();
|
||||
for (LimitingResourceQueueElement each: queuesState.inTopologicalOrder(queueElements)) {
|
||||
result.addAll(assignLimitingResourceQueueElement(each));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,62 +73,70 @@ public class QueuesState {
|
|||
|
||||
private final Map<Long, LimitingResourceQueue> queuesByResourceId;
|
||||
|
||||
private static <T extends BaseEntity> Map<Long, T> byId(
|
||||
Collection<? extends T> entities) {
|
||||
Map<Long, T> result = new HashMap<Long, T>();
|
||||
private static <T extends BaseEntity> Map<Long, T> byId(Collection<? extends T> entities) {
|
||||
Map<Long, T> result = new HashMap<>();
|
||||
for (T each : entities) {
|
||||
result.put(each.getId(), each);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Map<Long, LimitingResourceQueue> byResourceId(
|
||||
Collection<? extends LimitingResourceQueue> limitingResourceQueues) {
|
||||
Map<Long, LimitingResourceQueue> result = new HashMap<Long, LimitingResourceQueue>();
|
||||
|
||||
Map<Long, LimitingResourceQueue> result = new HashMap<>();
|
||||
for (LimitingResourceQueue each : limitingResourceQueues) {
|
||||
result.put(each.getResource().getId(), each);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public QueuesState(
|
||||
List<LimitingResourceQueue> limitingResourceQueues,
|
||||
List<LimitingResourceQueueElement> unassignedLimitingResourceQueueElements) {
|
||||
this.queues = new ArrayList<LimitingResourceQueue>(
|
||||
limitingResourceQueues);
|
||||
this.unassignedElements = new ArrayList<LimitingResourceQueueElement>(
|
||||
unassignedLimitingResourceQueueElements);
|
||||
|
||||
this.queues = new ArrayList<>(limitingResourceQueues);
|
||||
this.unassignedElements = new ArrayList<>(unassignedLimitingResourceQueueElements);
|
||||
this.queuesById = byId(queues);
|
||||
this.elementsById = byId(allElements(limitingResourceQueues,
|
||||
unassignedLimitingResourceQueueElements));
|
||||
this.elementsById = byId(allElements(limitingResourceQueues, unassignedLimitingResourceQueueElements));
|
||||
this.queuesByResourceId = byResourceId(limitingResourceQueues);
|
||||
this.graph = buildGraph(getAllElements(unassignedElements, queues));
|
||||
}
|
||||
|
||||
private static DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> buildGraph(
|
||||
List<LimitingResourceQueueElement> allElements) {
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result = instantiateDirectedGraph();
|
||||
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result =
|
||||
instantiateDirectedGraph();
|
||||
|
||||
for (LimitingResourceQueueElement each : allElements) {
|
||||
result.addVertex(each);
|
||||
}
|
||||
|
||||
for (LimitingResourceQueueElement each : allElements) {
|
||||
Set<LimitingResourceQueueDependency> dependenciesAsOrigin = each
|
||||
.getDependenciesAsOrigin();
|
||||
Set<LimitingResourceQueueDependency> dependenciesAsOrigin = each.getDependenciesAsOrigin();
|
||||
|
||||
for (LimitingResourceQueueDependency eachDependency : dependenciesAsOrigin) {
|
||||
addDependency(result, eachDependency);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static SimpleDirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> instantiateDirectedGraph() {
|
||||
return new SimpleDirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency>(
|
||||
LimitingResourceQueueDependency.class);
|
||||
private static SimpleDirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency>
|
||||
instantiateDirectedGraph() {
|
||||
|
||||
return new SimpleDirectedGraph<>(LimitingResourceQueueDependency.class);
|
||||
}
|
||||
|
||||
private static void addDependency(
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result,
|
||||
DirectedGraph<LimitingResourceQueueElement,
|
||||
LimitingResourceQueueDependency> result,
|
||||
LimitingResourceQueueDependency dependency) {
|
||||
|
||||
LimitingResourceQueueElement origin = dependency.getHasAsOrigin();
|
||||
LimitingResourceQueueElement destination = dependency.getHasAsDestiny();
|
||||
result.addVertex(origin);
|
||||
|
|
@ -139,22 +147,27 @@ public class QueuesState {
|
|||
private static List<LimitingResourceQueueElement> getAllElements(
|
||||
List<LimitingResourceQueueElement> unassigned,
|
||||
List<LimitingResourceQueue> queues) {
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
result.addAll(unassigned);
|
||||
|
||||
for (LimitingResourceQueue each : queues) {
|
||||
result.addAll(each.getLimitingResourceQueueElements());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueueElement> allElements(
|
||||
List<LimitingResourceQueue> queues,
|
||||
List<LimitingResourceQueueElement> unassigned) {
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
for (LimitingResourceQueue each : queues) {
|
||||
result.addAll(each.getLimitingResourceQueueElements());
|
||||
}
|
||||
result.addAll(unassigned);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -163,13 +176,11 @@ public class QueuesState {
|
|||
}
|
||||
|
||||
public ArrayList<LimitingResourceQueue> getQueuesOrderedByResourceName() {
|
||||
ArrayList<LimitingResourceQueue> result = new ArrayList<LimitingResourceQueue>(
|
||||
queues);
|
||||
ArrayList<LimitingResourceQueue> result = new ArrayList<>(queues);
|
||||
Collections.sort(result, new Comparator<LimitingResourceQueue>() {
|
||||
|
||||
@Override
|
||||
public int compare(LimitingResourceQueue arg0,
|
||||
LimitingResourceQueue arg1) {
|
||||
public int compare(LimitingResourceQueue arg0, LimitingResourceQueue arg1) {
|
||||
|
||||
if ( (arg0 == null) || (arg0.getResource().getName() == null) ) {
|
||||
return -1;
|
||||
|
|
@ -178,11 +189,13 @@ public class QueuesState {
|
|||
if ( (arg1 == null) || (arg1.getResource().getName() == null) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (arg0.getResource().getName().toLowerCase()
|
||||
.compareTo(arg1.getResource().getName().toLowerCase()));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
|
@ -191,8 +204,7 @@ public class QueuesState {
|
|||
return Collections.unmodifiableList(unassignedElements);
|
||||
}
|
||||
|
||||
public void assignedToQueue(LimitingResourceQueueElement element,
|
||||
LimitingResourceQueue queue) {
|
||||
public void assignedToQueue(LimitingResourceQueueElement element, LimitingResourceQueue queue) {
|
||||
Validate.isTrue(unassignedElements.contains(element));
|
||||
queue.addLimitingResourceQueueElement(element);
|
||||
unassignedElements.remove(element);
|
||||
|
|
@ -202,14 +214,14 @@ public class QueuesState {
|
|||
return queuesById.get(queue.getId());
|
||||
}
|
||||
|
||||
public LimitingResourceQueueElement getEquivalent(
|
||||
LimitingResourceQueueElement element) {
|
||||
public LimitingResourceQueueElement getEquivalent(LimitingResourceQueueElement element) {
|
||||
return elementsById.get(element.getId());
|
||||
}
|
||||
|
||||
public void unassingFromQueue(LimitingResourceQueueElement externalElement) {
|
||||
LimitingResourceQueueElement queueElement = getEquivalent(externalElement);
|
||||
LimitingResourceQueue queue = queueElement.getLimitingResourceQueue();
|
||||
|
||||
if ( queue != null ) {
|
||||
queue.removeLimitingResourceQueueElement(queueElement);
|
||||
unassignedElements.add(queueElement);
|
||||
|
|
@ -220,20 +232,19 @@ public class QueuesState {
|
|||
unassignedElements.remove(queueElement);
|
||||
}
|
||||
|
||||
public List<LimitingResourceQueue> getAssignableQueues(
|
||||
LimitingResourceQueueElement element) {
|
||||
final ResourceAllocation<?> resourceAllocation = element
|
||||
.getResourceAllocation();
|
||||
public List<LimitingResourceQueue> getAssignableQueues(LimitingResourceQueueElement element) {
|
||||
final ResourceAllocation<?> resourceAllocation = element.getResourceAllocation();
|
||||
|
||||
if ( resourceAllocation instanceof SpecificResourceAllocation ) {
|
||||
LimitingResourceQueue queue = getQueueFor(element
|
||||
.getResource());
|
||||
LimitingResourceQueue queue = getQueueFor(element.getResource());
|
||||
Validate.notNull(queue);
|
||||
return Collections.singletonList(queue);
|
||||
|
||||
} else if ( resourceAllocation instanceof GenericResourceAllocation ) {
|
||||
final GenericResourceAllocation generic = (GenericResourceAllocation) element
|
||||
.getResourceAllocation();
|
||||
final GenericResourceAllocation generic = (GenericResourceAllocation) element.getResourceAllocation();
|
||||
return findQueuesMatchingCriteria(generic);
|
||||
}
|
||||
|
||||
throw new RuntimeException("unexpected type of: " + resourceAllocation);
|
||||
}
|
||||
|
||||
|
|
@ -241,33 +252,32 @@ public class QueuesState {
|
|||
return queuesByResourceId.get(resource.getId());
|
||||
}
|
||||
|
||||
public InsertionRequirements getRequirementsFor(
|
||||
LimitingResourceQueueElement element) {
|
||||
List<LimitingResourceQueueDependency> dependenciesStart = new ArrayList<LimitingResourceQueueDependency>();
|
||||
List<LimitingResourceQueueDependency> dependenciesEnd = new ArrayList<LimitingResourceQueueDependency>();
|
||||
public InsertionRequirements getRequirementsFor(LimitingResourceQueueElement element) {
|
||||
List<LimitingResourceQueueDependency> dependenciesStart = new ArrayList<>();
|
||||
List<LimitingResourceQueueDependency> dependenciesEnd = new ArrayList<>();
|
||||
fillIncoming(element, dependenciesStart, dependenciesEnd);
|
||||
return InsertionRequirements.forElement(getEquivalent(element),
|
||||
dependenciesStart, dependenciesEnd);
|
||||
|
||||
return InsertionRequirements.forElement(getEquivalent(element), dependenciesStart, dependenciesEnd);
|
||||
}
|
||||
|
||||
public InsertionRequirements getRequirementsFor(
|
||||
LimitingResourceQueueElement element, DateAndHour startAt) {
|
||||
List<LimitingResourceQueueDependency> dependenciesStart = new ArrayList<LimitingResourceQueueDependency>();
|
||||
List<LimitingResourceQueueDependency> dependenciesEnd = new ArrayList<LimitingResourceQueueDependency>();
|
||||
public InsertionRequirements getRequirementsFor(LimitingResourceQueueElement element, DateAndHour startAt) {
|
||||
List<LimitingResourceQueueDependency> dependenciesStart = new ArrayList<>();
|
||||
List<LimitingResourceQueueDependency> dependenciesEnd = new ArrayList<>();
|
||||
fillIncoming(element, dependenciesStart, dependenciesEnd);
|
||||
return InsertionRequirements.forElement(getEquivalent(element),
|
||||
dependenciesStart, dependenciesEnd, startAt);
|
||||
|
||||
return InsertionRequirements.forElement(getEquivalent(element), dependenciesStart, dependenciesEnd, startAt);
|
||||
}
|
||||
|
||||
private void fillIncoming(LimitingResourceQueueElement element,
|
||||
List<LimitingResourceQueueDependency> dependenciesStart,
|
||||
List<LimitingResourceQueueDependency> dependenciesEnd) {
|
||||
Set<LimitingResourceQueueDependency> incoming = graph
|
||||
.incomingEdgesOf(element);
|
||||
|
||||
Set<LimitingResourceQueueDependency> incoming = graph.incomingEdgesOf(element);
|
||||
for (LimitingResourceQueueDependency each : incoming) {
|
||||
List<LimitingResourceQueueDependency> addingTo = each
|
||||
.modifiesDestinationStart() ? dependenciesStart
|
||||
: dependenciesEnd;
|
||||
|
||||
List<LimitingResourceQueueDependency> addingTo =
|
||||
each.modifiesDestinationStart() ? dependenciesStart : dependenciesEnd;
|
||||
|
||||
if ( each.isOriginNotDetached() ) {
|
||||
addingTo.add(each);
|
||||
} else {
|
||||
|
|
@ -276,12 +286,13 @@ public class QueuesState {
|
|||
}
|
||||
}
|
||||
|
||||
private void fillIncoming(LimitingResourceQueueDependency next,
|
||||
List<LimitingResourceQueueDependency> result) {
|
||||
Set<LimitingResourceQueueDependency> incoming = graph
|
||||
.incomingEdgesOf(next.getHasAsOrigin());
|
||||
private void fillIncoming(LimitingResourceQueueDependency next, List<LimitingResourceQueueDependency> result) {
|
||||
Set<LimitingResourceQueueDependency> incoming = graph.incomingEdgesOf(next.getHasAsOrigin());
|
||||
|
||||
for (LimitingResourceQueueDependency each : incoming) {
|
||||
|
||||
if ( each.propagatesThrough(next) ) {
|
||||
|
||||
if ( each.isOriginNotDetached() ) {
|
||||
result.add(each);
|
||||
} else {
|
||||
|
|
@ -295,36 +306,36 @@ public class QueuesState {
|
|||
* @return all the gaps that could potentially fit <code>element</code>
|
||||
* ordered by start date
|
||||
*/
|
||||
public List<GapOnQueue> getPotentiallyValidGapsFor(
|
||||
InsertionRequirements requirements) {
|
||||
List<LimitingResourceQueue> assignableQueues = getAssignableQueues(requirements
|
||||
.getElement());
|
||||
public List<GapOnQueue> getPotentiallyValidGapsFor(InsertionRequirements requirements) {
|
||||
List<LimitingResourceQueue> assignableQueues = getAssignableQueues(requirements.getElement());
|
||||
List<List<GapOnQueue>> allGaps = gapsFor(assignableQueues, requirements);
|
||||
|
||||
return GapsMergeSort.sort(allGaps);
|
||||
}
|
||||
|
||||
private List<List<GapOnQueue>> gapsFor(
|
||||
List<LimitingResourceQueue> assignableQueues,
|
||||
private List<List<GapOnQueue>> gapsFor(List<LimitingResourceQueue> assignableQueues,
|
||||
InsertionRequirements requirements) {
|
||||
List<List<GapOnQueue>> result = new ArrayList<List<GapOnQueue>>();
|
||||
|
||||
List<List<GapOnQueue>> result = new ArrayList<>();
|
||||
for (LimitingResourceQueue each : assignableQueues) {
|
||||
result.add(each.getGapsPotentiallyValidFor(requirements));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueue> findQueuesMatchingCriteria(GenericResourceAllocation generic) {
|
||||
List<LimitingResourceQueue> result = new ArrayList<LimitingResourceQueue>();
|
||||
List<LimitingResourceQueue> result = new ArrayList<>();
|
||||
ResourceEnum resourceType = generic.getResourceType();
|
||||
Set<Criterion> criteria = generic.getCriterions();
|
||||
|
||||
for (LimitingResourceQueue each : queues) {
|
||||
Resource resource = each.getResource();
|
||||
if (resource.getType().equals(resourceType)
|
||||
&& resource.satisfiesCriterionsAtSomePoint(criteria)) {
|
||||
if ( resource.getType().equals(resourceType) && resource.satisfiesCriterionsAtSomePoint(criteria) ) {
|
||||
result.add(each);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -336,19 +347,19 @@ public class QueuesState {
|
|||
public final QueueDependencyType type;
|
||||
|
||||
public static Edge from(LimitingResourceQueueDependency dependency) {
|
||||
return new Edge(dependency.getHasAsOrigin(),
|
||||
dependency.getHasAsDestiny(), dependency.getType());
|
||||
return new Edge(dependency.getHasAsOrigin(), dependency.getHasAsDestiny(), dependency.getType());
|
||||
}
|
||||
|
||||
public static Edge insertionOrder(
|
||||
LimitingResourceQueueElement element,
|
||||
public static Edge insertionOrder(LimitingResourceQueueElement element,
|
||||
LimitingResourceQueueElement contiguousNext) {
|
||||
return new Edge(element, contiguousNext,
|
||||
QueueDependencyType.END_START);
|
||||
|
||||
return new Edge(element, contiguousNext, QueueDependencyType.END_START);
|
||||
}
|
||||
|
||||
private Edge(LimitingResourceQueueElement source,
|
||||
LimitingResourceQueueElement target, QueueDependencyType type) {
|
||||
LimitingResourceQueueElement target,
|
||||
QueueDependencyType type) {
|
||||
|
||||
Validate.notNull(source);
|
||||
Validate.notNull(target);
|
||||
Validate.notNull(type);
|
||||
|
|
@ -359,18 +370,20 @@ public class QueuesState {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder().append(source).append(target)
|
||||
.append(type).toHashCode();
|
||||
return new HashCodeBuilder().append(source).append(target).append(type).toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( obj instanceof Edge ) {
|
||||
Edge another = (Edge) obj;
|
||||
return new EqualsBuilder().append(source, another.source)
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(source, another.source)
|
||||
.append(target, another.target)
|
||||
.append(type, another.type).isEquals();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -378,36 +391,41 @@ public class QueuesState {
|
|||
|
||||
public DirectedGraph<LimitingResourceQueueElement, Edge> getPotentiallyAffectedByInsertion(
|
||||
LimitingResourceQueueElement element) {
|
||||
|
||||
DirectedMultigraph<LimitingResourceQueueElement, Edge> result;
|
||||
result = asEdges(onQueues(buildOutgoingGraphFor(getEquivalent(element))));
|
||||
Map<LimitingResourceQueue, LimitingResourceQueueElement> earliestForEachQueue = earliest(byQueue(result
|
||||
.vertexSet()));
|
||||
for (Entry<LimitingResourceQueue, LimitingResourceQueueElement> each : earliestForEachQueue
|
||||
.entrySet()) {
|
||||
|
||||
Map<LimitingResourceQueue, LimitingResourceQueueElement> earliestForEachQueue =
|
||||
earliest(byQueue(result.vertexSet()));
|
||||
|
||||
for (Entry<LimitingResourceQueue, LimitingResourceQueueElement> each : earliestForEachQueue.entrySet()) {
|
||||
LimitingResourceQueue queue = each.getKey();
|
||||
LimitingResourceQueueElement earliest = each.getValue();
|
||||
addInsertionOrderOnQueueEdges(result, earliest,
|
||||
queue.getElementsAfter(earliest));
|
||||
addInsertionOrderOnQueueEdges(result, earliest, queue.getElementsAfter(earliest));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> onQueues(
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> graph) {
|
||||
|
||||
SimpleDirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result;
|
||||
result = instantiateDirectedGraph();
|
||||
|
||||
for (LimitingResourceQueueDependency each : graph.edgeSet()) {
|
||||
if (!each.getHasAsOrigin().isDetached()
|
||||
&& !each.getHasAsDestiny().isDetached()) {
|
||||
if ( !each.getHasAsOrigin().isDetached() && !each.getHasAsDestiny().isDetached() ) {
|
||||
addDependency(result, each);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private DirectedMultigraph<LimitingResourceQueueElement, Edge> asEdges(
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> graph) {
|
||||
|
||||
DirectedMultigraph<LimitingResourceQueueElement, Edge> result = instantiateMultiGraph();
|
||||
for (LimitingResourceQueueDependency each : graph.edgeSet()) {
|
||||
Edge edge = Edge.from(each);
|
||||
|
|
@ -415,48 +433,53 @@ public class QueuesState {
|
|||
result.addVertex(edge.target);
|
||||
result.addEdge(edge.source, edge.target, edge);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private DirectedMultigraph<LimitingResourceQueueElement, Edge> instantiateMultiGraph() {
|
||||
return new DirectedMultigraph<LimitingResourceQueueElement, Edge>(
|
||||
Edge.class);
|
||||
return new DirectedMultigraph<>(Edge.class);
|
||||
}
|
||||
|
||||
private Map<LimitingResourceQueue, List<LimitingResourceQueueElement>> byQueue(
|
||||
Collection<? extends LimitingResourceQueueElement> vertexSet) {
|
||||
Map<LimitingResourceQueue, List<LimitingResourceQueueElement>> result = new HashMap<LimitingResourceQueue, List<LimitingResourceQueueElement>>();
|
||||
|
||||
Map<LimitingResourceQueue, List<LimitingResourceQueueElement>> result = new HashMap<>();
|
||||
for (LimitingResourceQueueElement each : vertexSet) {
|
||||
assert each.getLimitingResourceQueue() != null;
|
||||
forQueue(result, each.getLimitingResourceQueue()).add(each);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueueElement> forQueue(
|
||||
Map<LimitingResourceQueue, List<LimitingResourceQueueElement>> map,
|
||||
LimitingResourceQueue queue) {
|
||||
|
||||
List<LimitingResourceQueueElement> result = map.get(queue);
|
||||
if ( result == null ) {
|
||||
result = new ArrayList<LimitingResourceQueueElement>();
|
||||
result = new ArrayList<>();
|
||||
map.put(queue, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Map<LimitingResourceQueue, LimitingResourceQueueElement> earliest(
|
||||
Map<LimitingResourceQueue, List<LimitingResourceQueueElement>> byQueue) {
|
||||
Map<LimitingResourceQueue, LimitingResourceQueueElement> result = new HashMap<LimitingResourceQueue, LimitingResourceQueueElement>();
|
||||
for (Entry<LimitingResourceQueue, List<LimitingResourceQueueElement>> each : byQueue
|
||||
.entrySet()) {
|
||||
|
||||
Map<LimitingResourceQueue, LimitingResourceQueueElement> result = new HashMap<>();
|
||||
for (Entry<LimitingResourceQueue, List<LimitingResourceQueueElement>> each : byQueue.entrySet()) {
|
||||
result.put(each.getKey(), earliest(each.getValue()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static LimitingResourceQueueElement earliest(
|
||||
List<LimitingResourceQueueElement> list) {
|
||||
private static LimitingResourceQueueElement earliest(List<LimitingResourceQueueElement> list) {
|
||||
Validate.isTrue(!list.isEmpty());
|
||||
|
||||
return Collections.min(list, LimitingResourceQueueElement.byStartTimeComparator());
|
||||
}
|
||||
|
||||
|
|
@ -464,15 +487,16 @@ public class QueuesState {
|
|||
DirectedGraph<LimitingResourceQueueElement, Edge> result,
|
||||
LimitingResourceQueueElement first,
|
||||
List<LimitingResourceQueueElement> elements) {
|
||||
|
||||
LimitingResourceQueueElement previous = first;
|
||||
for (LimitingResourceQueueElement each : elements) {
|
||||
|
||||
// FIXME: Fixs bug #553, "No such vertex in graph". It seems that
|
||||
// , for some reason, some of the vertexs (queue elements) are not in graph
|
||||
// at this point
|
||||
// Fixes bug #553, "No such vertex in graph".
|
||||
// It seems that, for some reason, some of the vertexes (queue elements) are not in graph at this point
|
||||
if ( !result.containsVertex(previous) ) {
|
||||
result.addVertex(previous);
|
||||
}
|
||||
|
||||
if ( !result.containsVertex(each) ) {
|
||||
result.addVertex(each);
|
||||
}
|
||||
|
|
@ -490,32 +514,45 @@ public class QueuesState {
|
|||
*/
|
||||
public List<LimitingResourceQueueElement> getInsertionsToBeDoneFor(
|
||||
LimitingResourceQueueElement externalQueueElement) {
|
||||
|
||||
LimitingResourceQueueElement queueElement = getEquivalent(externalQueueElement);
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> subGraph = buildOutgoingGraphFor(queueElement);
|
||||
CycleDetector<LimitingResourceQueueElement, LimitingResourceQueueDependency> cycleDetector = cycleDetector(subGraph);
|
||||
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> subGraph =
|
||||
buildOutgoingGraphFor(queueElement);
|
||||
|
||||
CycleDetector<LimitingResourceQueueElement, LimitingResourceQueueDependency> cycleDetector =
|
||||
cycleDetector(subGraph);
|
||||
|
||||
if ( cycleDetector.detectCycles() ) {
|
||||
throw new IllegalStateException("subgraph has cycles");
|
||||
}
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
result.add(queueElement);
|
||||
result.addAll(getElementsOrderedTopologically(subGraph));
|
||||
unassignFromQueues(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> buildOutgoingGraphFor(
|
||||
LimitingResourceQueueElement queueElement) {
|
||||
SimpleDirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result = instantiateDirectedGraph();
|
||||
|
||||
SimpleDirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result =
|
||||
instantiateDirectedGraph();
|
||||
|
||||
buildOutgoingGraphFor(result, queueElement);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void buildOutgoingGraphFor(
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result,
|
||||
LimitingResourceQueueElement element) {
|
||||
Set<LimitingResourceQueueDependency> outgoingEdgesOf = graph
|
||||
.outgoingEdgesOf(element);
|
||||
|
||||
Set<LimitingResourceQueueDependency> outgoingEdgesOf = graph.outgoingEdgesOf(element);
|
||||
result.addVertex(element);
|
||||
|
||||
for (LimitingResourceQueueDependency each : outgoingEdgesOf) {
|
||||
addDependency(result, each);
|
||||
buildOutgoingGraphFor(result, each.getHasAsDestiny());
|
||||
|
|
@ -524,18 +561,18 @@ public class QueuesState {
|
|||
|
||||
private CycleDetector<LimitingResourceQueueElement, LimitingResourceQueueDependency> cycleDetector(
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> subGraph) {
|
||||
return new CycleDetector<LimitingResourceQueueElement, LimitingResourceQueueDependency>(
|
||||
subGraph);
|
||||
|
||||
return new CycleDetector<>(subGraph);
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueueElement> getElementsOrderedTopologically(
|
||||
DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> subGraph) {
|
||||
|
||||
return onlyAssigned(toList(topologicalIterator(subGraph)));
|
||||
}
|
||||
|
||||
public static <V, E> TopologicalOrderIterator<V, E> topologicalIterator(
|
||||
DirectedGraph<V, E> subGraph) {
|
||||
return new TopologicalOrderIterator<V, E>(subGraph);
|
||||
public static <V, E> TopologicalOrderIterator<V, E> topologicalIterator(DirectedGraph<V, E> subGraph) {
|
||||
return new TopologicalOrderIterator<>(subGraph);
|
||||
}
|
||||
|
||||
public static <T> List<T> toList(final Iterator<T> iterator) {
|
||||
|
|
@ -543,17 +580,18 @@ public class QueuesState {
|
|||
while (iterator.hasNext()) {
|
||||
result.add(iterator.next());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueueElement> onlyAssigned(
|
||||
List<LimitingResourceQueueElement> list) {
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<LimitingResourceQueueElement>();
|
||||
private List<LimitingResourceQueueElement> onlyAssigned(List<LimitingResourceQueueElement> list) {
|
||||
List<LimitingResourceQueueElement> result = new ArrayList<>();
|
||||
for (LimitingResourceQueueElement each : list) {
|
||||
if ( !each.isDetached() ) {
|
||||
result.add(each);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -586,17 +624,18 @@ public class QueuesState {
|
|||
unassignedElements.add(newElement);
|
||||
elementsById.put(newElement.getId(), newElement);
|
||||
graph.addVertex(newElement);
|
||||
|
||||
for (LimitingResourceQueueDependency each: newElement.getDependenciesAsOrigin()) {
|
||||
graph.addEdge(each.getHasAsOrigin(), each.getHasAsDestiny(), each);
|
||||
}
|
||||
|
||||
for (LimitingResourceQueueDependency each: newElement.getDependenciesAsDestiny()) {
|
||||
graph.addEdge(each.getHasAsOrigin(), each.getHasAsDestiny(), each);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void idChangedFor(Long previousId,
|
||||
LimitingResourceQueueElement element) {
|
||||
public void idChangedFor(Long previousId, LimitingResourceQueueElement element) {
|
||||
elementsById.remove(previousId);
|
||||
elementsById.put(element.getId(), element);
|
||||
}
|
||||
|
|
@ -613,21 +652,25 @@ public class QueuesState {
|
|||
*/
|
||||
private DirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> buildSubgraphFor(
|
||||
List<LimitingResourceQueueElement> queueElements) {
|
||||
SimpleDirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result = instantiateDirectedGraph();
|
||||
|
||||
SimpleDirectedGraph<LimitingResourceQueueElement, LimitingResourceQueueDependency> result =
|
||||
instantiateDirectedGraph();
|
||||
|
||||
// Iterate through elements and construct graph
|
||||
for (LimitingResourceQueueElement each : queueElements) {
|
||||
result.addVertex(each);
|
||||
for (LimitingResourceQueueDependency dependency : each
|
||||
.getDependenciesAsOrigin()) {
|
||||
LimitingResourceQueueElement destiny = dependency
|
||||
.getHasAsDestiny();
|
||||
|
||||
for (LimitingResourceQueueDependency dependency : each.getDependenciesAsOrigin()) {
|
||||
|
||||
LimitingResourceQueueElement destiny = dependency.getHasAsDestiny();
|
||||
|
||||
if ( queueElements.contains(destiny) ) {
|
||||
// Add source, destiny and edge between them
|
||||
addDependency(result, dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -644,30 +687,34 @@ public class QueuesState {
|
|||
*/
|
||||
public List<GapOnQueueWithQueueElement> getGapsWithQueueElementsOnQueueSince(
|
||||
LimitingResourceQueue queue, DateAndHour allocationTime) {
|
||||
|
||||
return gapsWithQueueElementsFor(queue, allocationTime);
|
||||
}
|
||||
|
||||
private List<GapOnQueueWithQueueElement> gapsWithQueueElementsFor(
|
||||
LimitingResourceQueue queue, DateAndHour allocationTime) {
|
||||
|
||||
List<GapOnQueueWithQueueElement> result = new ArrayList<GapOnQueueWithQueueElement>();
|
||||
List<GapOnQueueWithQueueElement> result = new ArrayList<>();
|
||||
|
||||
DateAndHour previousEnd = null;
|
||||
for (LimitingResourceQueueElement each : queue
|
||||
.getLimitingResourceQueueElements()) {
|
||||
for (LimitingResourceQueueElement each : queue.getLimitingResourceQueueElements()) {
|
||||
|
||||
DateAndHour startTime = each.getStartTime();
|
||||
|
||||
if ( !startTime.isBefore(allocationTime) ) {
|
||||
|
||||
if ( previousEnd == null || startTime.isAfter(previousEnd) ) {
|
||||
Gap gap = Gap.create(queue.getResource(), previousEnd,
|
||||
startTime);
|
||||
result.add(GapOnQueueWithQueueElement.create(
|
||||
gap.onQueue(queue), each));
|
||||
Gap gap = Gap.create(queue.getResource(), previousEnd, startTime);
|
||||
result.add(GapOnQueueWithQueueElement.create(gap.onQueue(queue), each));
|
||||
}
|
||||
}
|
||||
|
||||
previousEnd = each.getEndTime();
|
||||
}
|
||||
|
||||
Gap gap = Gap.create(queue.getResource(), previousEnd, null);
|
||||
result.add(GapOnQueueWithQueueElement.create(gap.onQueue(queue), null));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,8 +68,12 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
|
||||
WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE,
|
||||
@ContextConfiguration(locations = {
|
||||
BUSINESS_SPRING_CONFIG_FILE,
|
||||
|
||||
WEBAPP_SPRING_CONFIG_FILE,
|
||||
WEBAPP_SPRING_CONFIG_TEST_FILE,
|
||||
|
||||
WEBAPP_SPRING_SECURITY_CONFIG_FILE,
|
||||
WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE })
|
||||
public class SubcontractServiceTest {
|
||||
|
|
@ -106,14 +110,12 @@ public class SubcontractServiceTest {
|
|||
OrderLineDTO orderLineDTO = new OrderLineDTO();
|
||||
orderLineDTO.name = "Test";
|
||||
orderLineDTO.code = orderLineCode;
|
||||
orderLineDTO.initDate = DateConverter
|
||||
.toXMLGregorianCalendar(new Date());
|
||||
orderLineDTO.initDate = DateConverter.toXMLGregorianCalendar(new Date());
|
||||
|
||||
return orderLineDTO;
|
||||
}
|
||||
|
||||
private ExternalCompany getClientExternalCompanySaved(String name,
|
||||
String nif) {
|
||||
private ExternalCompany getClientExternalCompanySaved(String name, String nif) {
|
||||
ExternalCompany externalCompany = ExternalCompany.create(name, nif);
|
||||
externalCompany.setClient(true);
|
||||
|
||||
|
|
@ -147,8 +149,9 @@ public class SubcontractServiceTest {
|
|||
SubcontractedTaskDataDTO subcontractedTaskDataDTO = new SubcontractedTaskDataDTO();
|
||||
subcontractedTaskDataDTO.orderElementDTO = orderElementDTO;
|
||||
|
||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = subcontractService
|
||||
.subcontract(subcontractedTaskDataDTO).instanceConstraintViolationsList;
|
||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
|
||||
subcontractService.subcontract(subcontractedTaskDataDTO).instanceConstraintViolationsList;
|
||||
|
||||
assertThat(instanceConstraintViolationsList.size(), equalTo(1));
|
||||
|
||||
assertThat(orderDAO.getOrders().size(), equalTo(previous));
|
||||
|
|
@ -159,14 +162,14 @@ public class SubcontractServiceTest {
|
|||
public void invalidSubcontractedTaskDataWithoutOrderElement() {
|
||||
int previous = orderDAO.getOrders().size();
|
||||
|
||||
ExternalCompany externalCompany = getClientExternalCompanySaved(
|
||||
"Company", "company-nif");
|
||||
ExternalCompany externalCompany = getClientExternalCompanySaved("Company", "company-nif");
|
||||
|
||||
SubcontractedTaskDataDTO subcontractedTaskDataDTO = new SubcontractedTaskDataDTO();
|
||||
subcontractedTaskDataDTO.externalCompanyNif = externalCompany.getNif();
|
||||
|
||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = subcontractService
|
||||
.subcontract(subcontractedTaskDataDTO).instanceConstraintViolationsList;
|
||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
|
||||
subcontractService.subcontract(subcontractedTaskDataDTO).instanceConstraintViolationsList;
|
||||
|
||||
assertThat(instanceConstraintViolationsList.size(), equalTo(1));
|
||||
|
||||
assertThat(orderDAO.getOrders().size(), equalTo(previous));
|
||||
|
|
@ -180,8 +183,7 @@ public class SubcontractServiceTest {
|
|||
String orderLineCode = "order-line-code";
|
||||
|
||||
OrderElementDTO orderElementDTO = givenBasicOrderLineDTO(orderLineCode);
|
||||
ExternalCompany externalCompany = getClientExternalCompanySaved(
|
||||
"Company", "company-nif");
|
||||
ExternalCompany externalCompany = getClientExternalCompanySaved("Company", "company-nif");
|
||||
|
||||
SubcontractedTaskDataDTO subcontractedTaskDataDTO = new SubcontractedTaskDataDTO();
|
||||
subcontractedTaskDataDTO.orderElementDTO = orderElementDTO;
|
||||
|
|
@ -194,8 +196,9 @@ public class SubcontractServiceTest {
|
|||
subcontractedTaskDataDTO.subcontractedCode = orderCustomerReference;
|
||||
subcontractedTaskDataDTO.subcontractPrice = orderBudget;
|
||||
|
||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = subcontractService
|
||||
.subcontract(subcontractedTaskDataDTO).instanceConstraintViolationsList;
|
||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
|
||||
subcontractService.subcontract(subcontractedTaskDataDTO).instanceConstraintViolationsList;
|
||||
|
||||
assertThat(instanceConstraintViolationsList.size(), equalTo(0));
|
||||
|
||||
assertThat(orderDAO.getOrders().size(), equalTo(previous + 1));
|
||||
|
|
@ -205,14 +208,11 @@ public class SubcontractServiceTest {
|
|||
assertTrue(order.isCodeAutogenerated());
|
||||
assertNotNull(order.getExternalCode());
|
||||
assertThat(order.getExternalCode(), equalTo(orderLineCode));
|
||||
assertThat(order.getState(),
|
||||
equalTo(OrderStatusEnum.OUTSOURCED));
|
||||
assertThat(order.getState(), equalTo(OrderStatusEnum.OUTSOURCED));
|
||||
assertThat(order.getWorkHours(), equalTo(0));
|
||||
assertThat(order.getCustomer().getId(),
|
||||
equalTo(externalCompany.getId()));
|
||||
assertThat(order.getCustomer().getId(), equalTo(externalCompany.getId()));
|
||||
assertThat(order.getName(), equalTo(orderName));
|
||||
assertThat(order.getCustomerReference(),
|
||||
equalTo(orderCustomerReference));
|
||||
assertThat(order.getCustomerReference(), equalTo(orderCustomerReference));
|
||||
assertThat(order.getTotalManualBudget(), equalTo(orderBudget));
|
||||
|
||||
List<OrderElement> children = order.getChildren();
|
||||
|
|
|
|||
4
pom.xml
4
pom.xml
|
|
@ -461,8 +461,8 @@
|
|||
<!-- JGraphT -->
|
||||
<dependency>
|
||||
<groupId>org.jgrapht</groupId>
|
||||
<artifactId>jgrapht-jdk1.5</artifactId>
|
||||
<version>0.7.3</version>
|
||||
<artifactId>jgrapht-core</artifactId>
|
||||
<version>0.9.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Jfreechart -->
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue