001/* 002 * Copyright (C) 2022 - 2023, the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.github.ascopes.jct.filemanagers; 017 018import io.github.ascopes.jct.utils.ToStringBuilder; 019import java.util.Objects; 020import javax.tools.JavaFileManager.Location; 021import org.apiguardian.api.API; 022import org.apiguardian.api.API.Status; 023import org.jspecify.annotations.Nullable; 024 025/** 026 * Handle that represents the location of a module. 027 * 028 * @author Ashley Scopes 029 * @since 0.0.1 030 */ 031@API(since = "0.0.1", status = Status.STABLE) 032public final class ModuleLocation implements Location { 033 034 private final Location parent; 035 private final String moduleName; 036 private final String name; 037 038 /** 039 * Initialize the location. 040 * 041 * @param parent the parent location. 042 * @param moduleName the module name. 043 * @throws IllegalArgumentException if the parent location is not an output location or a 044 * module-oriented location. 045 */ 046 public ModuleLocation(Location parent, String moduleName) { 047 Objects.requireNonNull(parent, "parent"); 048 Objects.requireNonNull(moduleName, "moduleName"); 049 050 if (!parent.isOutputLocation() && !parent.isModuleOrientedLocation()) { 051 throw new IllegalArgumentException( 052 "The parent of a module location must be either an output location " 053 + "or be module-oriented, but got " 054 + parent.getName() 055 ); 056 } 057 058 this.parent = parent; 059 this.moduleName = moduleName; 060 name = parent.getName() + "[" + moduleName + "]"; 061 } 062 063 /** 064 * Get the parent location. 065 * 066 * @return the parent location. 067 */ 068 public Location getParent() { 069 return parent; 070 } 071 072 /** 073 * Get the module name. 074 * 075 * @return the module name. 076 */ 077 public String getModuleName() { 078 return moduleName; 079 } 080 081 @Override 082 public String getName() { 083 return name; 084 } 085 086 @Override 087 public boolean isOutputLocation() { 088 return parent.isOutputLocation(); 089 } 090 091 @Override 092 public boolean isModuleOrientedLocation() { 093 // Module locations cannot be module-oriented, but their parents can be. 094 return false; 095 } 096 097 @Override 098 public boolean equals(@Nullable Object other) { 099 if (!(other instanceof ModuleLocation)) { 100 return false; 101 } 102 103 var that = (ModuleLocation) other; 104 105 return parent.equals(that.parent) 106 && moduleName.equals(that.moduleName); 107 } 108 109 @Override 110 public int hashCode() { 111 return Objects.hash(parent, moduleName); 112 } 113 114 @Override 115 public String toString() { 116 return new ToStringBuilder(this) 117 .attribute("parent", parent) 118 .attribute("moduleName", moduleName) 119 .toString(); 120 } 121}