/** * Yobi, Project Hosting SW * * Copyright 2013 NAVER Corp. * http://yobi.io * * @author Yi EungJun * * 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 models.resource; import actions.support.PathParser; import models.*; import models.enumeration.ResourceType; import play.db.ebean.Model; import playRepository.Commit; import playRepository.RepositoryService; import utils.Config; import java.util.EnumSet; public abstract class Resource { public static boolean exists(ResourceType type, String id) { Model.Finder<Long, ? extends Model> finder; switch(type) { case ISSUE_POST: finder = Issue.finder; break; case ISSUE_ASSIGNEE: finder = Assignee.finder; break; case ISSUE_COMMENT: finder = IssueComment.find; break; case NONISSUE_COMMENT: finder = PostingComment.find; break; case LABEL: finder = Label.find; break; case BOARD_POST: finder = Posting.finder; break; case USER: finder = User.find; break; case PROJECT: finder = Project.find; break; case ATTACHMENT: finder = Attachment.find; break; case MILESTONE: finder = Milestone.find; break; case COMMIT_COMMENT: finder = CommitComment.find; break; case PULL_REQUEST: finder = PullRequest.finder; break; case REVIEW_COMMENT: finder = ReviewComment.find; break; case ORGANIZATION: finder = Organization.find; break; case COMMIT: try { String[] pair = id.split(":"); Project project = Project.find.byId(Long.valueOf(pair[0])); return RepositoryService.getRepository(project).getCommit(pair[1]) != null; } catch (Exception e) { play.Logger.error("Failed to determine whether the commit exists", e); return false; } case COMMENT_THREAD: finder = CommentThread.find; break; default: throw new IllegalArgumentException(getInvalidResourceTypeMessage(type)); } return finder.byId(Long.valueOf(id)) != null; } public static String getInvalidResourceTypeMessage(ResourceType resourceType) { if (EnumSet.allOf(ResourceType.class).contains(resourceType)) { return "Unsupported resource type " + resourceType; } else { return "Unknown resource type " + resourceType; } } public static Resource get(ResourceType resourceType, String resourceId) { Resource resource; if (resourceType.equals(ResourceType.COMMIT)) { return Commit.getAsResource(resourceId); } Long longId = Long.valueOf(resourceId); switch(resourceType) { case ISSUE_POST: resource = Issue.finder.byId(longId).asResource(); break; case ISSUE_COMMENT: resource = IssueComment.find.byId(longId).asResource(); break; case NONISSUE_COMMENT: resource = PostingComment.find.byId(longId).asResource(); break; case LABEL: resource = Label.find.byId(longId).asResource(); break; case BOARD_POST: resource = Posting.finder.byId(longId).asResource(); break; case USER: resource = User.find.byId(longId).asResource(); break; case PROJECT: resource = Project.find.byId(longId).asResource(); break; case ATTACHMENT: resource = Attachment.find.byId(longId).asResource(); break; case MILESTONE: resource = Milestone.find.byId(longId).asResource(); break; case COMMIT_COMMENT: resource = CommitComment.find.byId(longId).asResource(); break; case PULL_REQUEST: return PullRequest.finder.byId(longId).asResource(); case USER_AVATAR: return User.find.byId(longId).avatarAsResource(); case REVIEW_COMMENT: return ReviewComment.find.byId(longId).asResource(); case ORGANIZATION: resource = Organization.find.byId(longId).asResource(); break; case COMMENT_THREAD: return CommentThread.find.byId(longId).asResource(); default: throw new IllegalArgumentException(getInvalidResourceTypeMessage(resourceType)); } return resource; } public ResourceParam asParameter() { return ResourceParam.get(this); } abstract public String getId(); abstract public Project getProject(); abstract public ResourceType getType(); public Resource getContainer() { return null; } public Long getAuthorId() { return null; } public boolean isAuthoredBy(User user) { return getAuthorId() != null && getAuthorId().equals(user.id); } public void delete() { throw new UnsupportedOperationException(); } public String getDetail() { Project project = getProject(); String path = getPath(); if (project != null && path != null) { return project + "/" + path; } else { return null; } } @Override public boolean equals(Object object) { if (this == object) return true; if (object == null || getClass() != object.getClass()) return false; Resource that = (Resource) object; if (!getId().equals(that.getId())) return false; if (!getType().equals(that.getType())) return false; return true; } @Override public int hashCode() { int result = 0; result = 31 * result + (getId() != null ? getId().hashCode() : 0); result = 31 * result + (getType() != null ? getType().hashCode() : 0); return result; } @Override public String toString() { return getPath(); } private String getPath() { return getType().resource() + "/" + getId(); } /** * @see {@link actions.IsAllowedAction} */ public static ResourceConvertible getResourceObject(PathParser parser, Project project, ResourceType resourceType) { switch (resourceType) { case PROJECT: return project; case MILESTONE: return Milestone.findById(Long.parseLong(parser.getPathSegment(3))); case BOARD_POST: return Posting.findByNumber(project, Long.parseLong(parser.getPathSegment(3))); case ISSUE_POST: return Issue.findByNumber(project, Long.parseLong(parser.getPathSegment(3))); case ISSUE_LABEL: return IssueLabel.finder.byId(Long.parseLong(parser.getPathSegment(4))); case PULL_REQUEST: return PullRequest.findOne(project, Long.parseLong(parser.getPathSegment(3))); case COMMIT_COMMENT: return CommitComment.find.byId(Long.parseLong(parser.getPathSegment(5))); case ISSUE_LABEL_CATEGORY: return IssueLabelCategory.find.byId(Long.parseLong(parser.getPathSegment(5))); default: throw new IllegalAccessError(getInvalidResourceTypeMessage(resourceType)); } } /** * Finds a resource by the given resource path. * * The format of resource path is as follows: * * resource-type "/" resource-id * * @param path * @return */ public static Resource findByPath(String path) { String[] segments = path.split("/"); if (segments.length < 2) { return null; } ResourceType resourceType; try { resourceType = ResourceType.getValue(segments[0]); } catch (IllegalArgumentException e) { return null; } return Resource.get(resourceType, segments[1]); } public String getMessageId() { return String.format("<%s@%s>", this, Config.getHostname()); } }