Java tutorial
/* * Copyright 2012 Kazumune Katagiri. (http://d.hatena.ne.jp/nemuzuka) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package jp.co.nemuzuka.service.impl; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import jp.co.nemuzuka.dao.MilestoneDao; import jp.co.nemuzuka.dao.TicketDao.Param; import jp.co.nemuzuka.entity.ChildKeyListEntity; import jp.co.nemuzuka.entity.TicketModelEx; import jp.co.nemuzuka.model.MilestoneModel; import jp.co.nemuzuka.service.GanttService; import jp.co.nemuzuka.service.TicketService; import jp.co.nemuzuka.utils.ConvertUtils; import jp.co.nemuzuka.utils.CurrentDateUtils; import jp.co.nemuzuka.utils.DateTimeUtils; import org.apache.commons.lang.StringUtils; import com.google.appengine.api.datastore.Key; /** * GanttService?. * @author k-katagiri */ public class GanttServiceImpl implements GanttService { TicketService ticketService = TicketServiceImpl.getInstance(); MilestoneDao milestoneDao = MilestoneDao.getInstance(); private static GanttServiceImpl impl = new GanttServiceImpl(); /** * ?. * @return */ public static GanttServiceImpl getInstance() { return impl; } /** * . */ private GanttServiceImpl() { } /* (? Javadoc) * @see jp.co.nemuzuka.service.GanttService#getList(jp.co.nemuzuka.dao.TicketDao.Param) */ @Override public Result getList(Param param) { //? List<TicketModelEx> ticketList = ticketService.getList(param, "", false); reCreateTicketList(ticketList); Result result = new Result(); result.ticketList = ticketList; //? Date startDate = null; Date endDate = null; if (StringUtils.isNotEmpty(param.milestone)) { MilestoneModel milestone = milestoneDao.get(param.milestone); if (milestone != null) { startDate = milestone.getStartDate(); endDate = milestone.getEndDate(); result.milestoneName = milestone.getMilestoneName(); SimpleDateFormat sdf = DateTimeUtils.createSdf("yyyyMMdd"); result.startDate = ConvertUtils.toString(startDate, sdf); result.endDate = ConvertUtils.toString(endDate, sdf); result.milestoneStartDate = ConvertUtils.toString(startDate, sdf); result.milestoneEndDate = ConvertUtils.toString(endDate, sdf); } } //???? setDate(result, startDate, endDate); reCreateTicketList(result.ticketList); return result; } /** * ???. * ?????????? * @param ticketList ? */ void reCreateTicketList(List<TicketModelEx> ticketList) { //Key????TicketMap??Key?????Ticket?Entity? Map<Key, TicketModelEx> map = new HashMap<Key, TicketModelEx>(); Map<Key, ChildKeyListEntity> parentMap = new LinkedHashMap<Key, ChildKeyListEntity>(); for (TicketModelEx target : ticketList) { Key key = target.getModel().getKey(); map.put(key, target); Key parentKey = target.getModel().getParentTicketKey(); ChildKeyListEntity entity = parentMap.get(parentKey); if (entity == null) { entity = new ChildKeyListEntity(); parentMap.put(parentKey, entity); } int index = entity.childKeys.size(); entity.childKeys.add(key); entity.childMap.put(key, index); entity.grandchildList.add(null); } boolean isContinue = true; Set<Key> doneParentKeySet = new HashSet<Key>(); while (isContinue) { int beforeSize = parentMap.size(); for (Map.Entry<Key, ChildKeyListEntity> e : parentMap.entrySet()) { Key parentKey = e.getKey(); if (parentKey == null) { //Key????Ticket????? continue; } if (doneParentKeySet.contains(parentKey)) { //???Key????? continue; } //??Key??????? if (moveParentKey(parentMap, parentKey, e.getValue())) { //?????Map???loop parentMap.remove(parentKey); break; } else { //??Key???????????? doneParentKeySet.add(parentKey); } } int afterSize = parentMap.size(); if (beforeSize == afterSize) { //?????Map??????? isContinue = false; } } //??Map???? createList(ticketList, map, parentMap); return; } /** * TicketList?. * Ticket?Map????List???? * @param ticketList TicketList * @param map Ticket?Map * @param parentMap Ticket?Map */ private void createList(List<TicketModelEx> ticketList, Map<Key, TicketModelEx> map, Map<Key, ChildKeyListEntity> parentMap) { ticketList.clear(); for (Map.Entry<Key, ChildKeyListEntity> e : parentMap.entrySet()) { ChildKeyListEntity targetEntity = e.getValue(); int nestingLevel = 0; setTicketList(targetEntity, nestingLevel, ticketList, map); } } /** * List. * ?TicketKeyList?List???? * Ticket????List????? * ?????? * @param targetEntity ?Ticket?Entity * @param nestingLevel ??? * @param ticketList TicketList * @param map Ticket?Map */ void setTicketList(ChildKeyListEntity targetEntity, int nestingLevel, List<TicketModelEx> ticketList, Map<Key, TicketModelEx> map) { //?TicketKeyList? int index = 0; for (Key key : targetEntity.childKeys) { TicketModelEx targetModelEx = map.get(key); targetModelEx.setNestingLevel(nestingLevel); ticketList.add(targetModelEx); //TicketKey??? ChildKeyListEntity grandchild = targetEntity.grandchildList.get(index); index++; if (grandchild == null) { continue; } setTicketList(grandchild, (nestingLevel + 1), ticketList, map); } } /** * ???. * ?Key??????????????? * @param parentMap Map * @param targetKey Key * @param targetEntity ? * @return ?Key???????????true */ boolean moveParentKey(Map<Key, ChildKeyListEntity> parentMap, Key targetKey, ChildKeyListEntity targetEntity) { for (Map.Entry<Key, ChildKeyListEntity> e : parentMap.entrySet()) { //???????? if (e.getKey() != null && e.getKey().equals(targetKey)) { continue; } ChildKeyListEntity entity = e.getValue(); if (moveParentKey(targetKey, entity, targetEntity)) { return true; } } return false; } /** * ???. * ?Key????????? * ?????? * ?????????????? * @param targetKey Key * @param checkTarget ??Ticket?Entity * @param targetEntity ? * @return ?Key???????????true */ boolean moveParentKey(Key targetKey, ChildKeyListEntity checkTarget, ChildKeyListEntity targetEntity) { //?????Key????? Integer index = checkTarget.childMap.get(targetKey); if (index != null) { checkTarget.grandchildList.set(index, targetEntity); return true; } else { //??Ticket?EntityList???????? for (ChildKeyListEntity target : checkTarget.grandchildList) { if (target != null) { if (moveParentKey(targetKey, target, targetEntity)) { return true; } } } } return false; } /** * ???. * @param result ? * @param startDate * @param endDate */ void setDate(Result result, Date startDate, Date endDate) { Date targetStartDate = startDate; Date targetEndDate = endDate; for (TicketModelEx target : result.ticketList) { Date ticketStartDate = target.getModel().getStartDate(); Date ticketEndDate = target.getModel().getPeriod(); if (ticketEndDate != null && ticketStartDate == null) { //???????????? //???????????? ticketStartDate = ticketEndDate; } targetStartDate = checkDate(ticketStartDate, targetStartDate, true); targetEndDate = checkDate(ticketEndDate, targetEndDate, false); } //?null???? if (targetStartDate == null) { targetStartDate = CurrentDateUtils.getInstance().getCurrentDate(); } //?null????1? if (targetEndDate == null) { targetEndDate = DateTimeUtils.addMonths(targetStartDate, 1); } //???????15????15? if (DateTimeUtils.getDays(targetStartDate, targetEndDate) < 15) { targetEndDate = DateTimeUtils.addDays(targetStartDate, 15); } //Ticket????null?????? replaceNullDate(result.ticketList, targetStartDate, targetEndDate); //?? SimpleDateFormat sdf = DateTimeUtils.createSdf("yyyyMMdd"); result.startDate = ConvertUtils.toString(targetStartDate, sdf); result.endDate = ConvertUtils.toString(targetEndDate, sdf); //?????? //????? if (StringUtils.isNotEmpty(result.milestoneName)) { if (StringUtils.isEmpty(result.milestoneStartDate)) { result.milestoneStartDate = result.startDate; result.updateStartDate = true; } if (StringUtils.isEmpty(result.milestoneEndDate)) { result.milestoneEndDate = result.endDate; result.updateEndDate = true; } } } /** * Ticket??null?. * Ticket??null?????null???????? * @param ticketList Ticket * @param startDate ? * @param endDate ? */ private void replaceNullDate(List<TicketModelEx> ticketList, Date startDate, Date endDate) { SimpleDateFormat sdf = DateTimeUtils.createSdf("yyyyMMdd"); String start = ConvertUtils.toString(startDate, sdf); String end = ConvertUtils.toString(endDate, sdf); for (TicketModelEx target : ticketList) { if (StringUtils.isEmpty(target.getStartDate())) { target.setStartDate(start); target.setUpdateStartDate(true); } if (StringUtils.isEmpty(target.getPeriod())) { target.setPeriod(end); target.setUpdatePeriod(true); } } } /** * ?. * ????? * ? < ???????? * ????? * ? > ???????? * @param targetDate ? * @param baseDate * @param startDate ?????true * @return */ private Date checkDate(Date targetDate, Date baseDate, boolean startDate) { if (baseDate == null) { return targetDate; } if (targetDate == null) { return baseDate; } if (startDate) { if (targetDate.getTime() < baseDate.getTime()) { return targetDate; } } else { if (targetDate.getTime() > baseDate.getTime()) { return targetDate; } } return baseDate; } }