001 /* 002 * Jpkg - Java library and tools for operating system package creation. 003 * 004 * Copyright (c) 2007 Three Rings Design, Inc. 005 * All rights reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without 008 * modification, are permitted provided that the following conditions 009 * are met: 010 * 1. Redistributions of source code must retain the above copyright 011 * notice, this list of conditions and the following disclaimer. 012 * 2. Redistributions in binary form must reproduce the above copyright 013 * notice, this list of conditions and the following disclaimer in the 014 * documentation and/or other materials provided with the distribution. 015 * 3. Neither the name of the copyright owner nor the names of contributors 016 * may be used to endorse or promote products derived from this software 017 * without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 029 * POSSIBILITY OF SUCH DAMAGE. 030 */ 031 package com.threerings.jpkg.debian; 032 033 import java.util.Enumeration; 034 import java.util.Map; 035 import java.util.TreeMap; 036 037 import javax.mail.internet.InternetHeaders; 038 039 import com.threerings.jpkg.PathPermissions; 040 import com.threerings.jpkg.PermissionsMap; 041 import com.threerings.jpkg.debian.dependency.DependencyAlternatives; 042 import com.threerings.jpkg.debian.dependency.PackageConflict; 043 import com.threerings.jpkg.debian.dependency.PackageConflicts; 044 import com.threerings.jpkg.debian.dependency.PackageDependencies; 045 import com.threerings.jpkg.debian.dependency.PackageDependency; 046 import com.threerings.jpkg.debian.dependency.PackageReplacement; 047 import com.threerings.jpkg.debian.dependency.PackageReplacements; 048 049 /** 050 * Stores meta information needed to create a new Debian package. 051 * @see <a href="http://www.debian.org/doc/debian-policy/ch-controlfields.html">Debian Policy Manual</a> 052 */ 053 public class PackageInfo 054 { 055 /** The default package section. */ 056 public static final PackageSection DEFAULT_SECTION = new PackageSection("misc"); 057 058 /** The default package priority. */ 059 public static final PackagePriority DEFAULT_PRIORITY = PackagePriority.OPTIONAL; 060 061 /** 062 * Construct a {@link PackageInfo} object with the supplied data. 063 * Default values will be set for the package section and priority. 064 * @see PackageInfo#DEFAULT_SECTION 065 * @see PackageInfo#DEFAULT_PRIORITY 066 */ 067 public PackageInfo (PackageName name, PackageVersion version, PackageArchitecture architecture, 068 PackageMaintainer maintainer, PackageDescription description) 069 { 070 this(name, version, architecture, maintainer, description, DEFAULT_SECTION, DEFAULT_PRIORITY); 071 } 072 073 /** 074 * Construct a fully populated {@link PackageInfo} with all required fields. 075 */ 076 public PackageInfo (PackageName name, PackageVersion version, PackageArchitecture architecture, 077 PackageMaintainer maintainer, PackageDescription description, 078 PackageSection section, PackagePriority priority) 079 { 080 _name = name; 081 _version = version; 082 _section = section; 083 _priority = priority; 084 _architecture = architecture; 085 _maintainer = maintainer; 086 _description = description; 087 088 assertValidFields(); 089 } 090 091 /** 092 * Add a {@link PathPermissions} object associated with a given path. 093 * @see PermissionsMap#addPathPermissions(String, PathPermissions) 094 * @throws InvalidPathException If the supplied path is invalid. 095 */ 096 public void addPathPermissions (String path, PathPermissions permissions) 097 { 098 _permissions.addPathPermissions(path, permissions); 099 } 100 101 /** 102 * Add a package dependency for this package. 103 */ 104 public void addDependency (PackageDependency dependency) 105 { 106 _dependencies.addDependency(dependency); 107 } 108 109 /** 110 * Add a dependency alternative for this package. 111 */ 112 public void addDependencyAlternative (DependencyAlternatives alternative) 113 { 114 _dependencies.addAlternative(alternative); 115 } 116 117 /** 118 * Add a package conflict for this package. 119 */ 120 public void addConflict (PackageConflict conflict) 121 { 122 _conflicts.addConflict(conflict); 123 } 124 125 /** 126 * Add a package replacement for this package. 127 */ 128 public void addReplacement (PackageReplacement replacement) 129 { 130 _replacements.addReplacement(replacement); 131 } 132 133 /** 134 * Add the defined package data to an RFC822 formatted header formatted for a Debian package 135 * control file. 136 * Order of fields determined from: 137 * <a href="http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles">Debian Policy Manual</a> 138 */ 139 public InternetHeaders getControlHeaders () 140 { 141 final InternetHeaders headers = new InternetHeaders(); 142 143 headers.addHeader(_name.getField(), _name.getFieldValue()); 144 headers.addHeader(_version.getField(), _version.getFieldValue()); 145 146 headers.addHeader(_section.getField(), _section.getFieldValue()); 147 headers.addHeader(_priority.getField(), _priority.getFieldValue()); 148 headers.addHeader(_architecture.getField(), _architecture.getFieldValue()); 149 if (_dependencies.size() > 0) { 150 headers.addHeader(_dependencies.getField(), _dependencies.getFieldValue()); 151 } 152 if (_conflicts.size() > 0) { 153 headers.addHeader(_conflicts.getField(), _conflicts.getFieldValue()); 154 } 155 if (_replacements.size() > 0) { 156 headers.addHeader(_replacements.getField(), _replacements.getFieldValue()); 157 } 158 headers.addHeader(_maintainer.getField(), _maintainer.getFieldValue()); 159 headers.addHeader(_description.getField(), _description.getFieldValue()); 160 161 return headers; 162 } 163 164 /** 165 * Return the PermissionsMap modifying the package referred to by this PackageInfo. 166 */ 167 public PermissionsMap getPermissionsMap () 168 { 169 return _permissions; 170 } 171 172 /** 173 * Sets a maintainer script for this package, replacing any existing script for that type. 174 */ 175 public void setMaintainerScript (MaintainerScript script) 176 { 177 _scripts.put(script.getType(), script); 178 } 179 180 /** 181 * Returns the MaintainerScripts defined for this package. 182 */ 183 public Map<MaintainerScript.Type, MaintainerScript> getMaintainerScripts () 184 { 185 return _scripts; 186 } 187 188 @Override // from Object 189 public String toString () 190 { 191 final StringBuilder builder = new StringBuilder(); 192 @SuppressWarnings("unchecked") 193 final 194 Enumeration<String> en = getControlHeaders().getAllHeaderLines(); 195 while (en.hasMoreElements()) 196 { 197 builder.append(en.nextElement()).append("\n"); 198 } 199 return builder.toString(); 200 } 201 202 /** 203 * Validates that none of the required fields were null. 204 */ 205 private void assertValidFields () 206 { 207 if (_name == null) throw new IllegalArgumentException("The PackageName cannot be null."); 208 if (_version == null) throw new IllegalArgumentException("The PackageVersion cannot be null."); 209 if (_section == null) throw new IllegalArgumentException("The PackageSection cannot be null."); 210 if (_priority == null) throw new IllegalArgumentException("The PackagePriority cannot be null."); 211 if (_architecture == null) throw new IllegalArgumentException("The PackageArchitecture cannot be null."); 212 if (_maintainer == null) throw new IllegalArgumentException("The PackageMaintainer cannot be null."); 213 if (_description == null) throw new IllegalArgumentException("The PackageDescription cannot be null."); 214 } 215 216 /** The package name. */ 217 private final PackageName _name; 218 219 /** The package version. */ 220 private final PackageVersion _version; 221 222 /** The package section, e.g. "web". */ 223 private final PackageSection _section; 224 225 /** The package priority, e.g. "optional". */ 226 private final PackagePriority _priority; 227 228 /** The package architecture, e.g. "i386". */ 229 private final PackageArchitecture _architecture; 230 231 /** A list of packages this package depends on. */ 232 private final PackageDependencies _dependencies = new PackageDependencies(); 233 234 /** A list of packages this package conflicts with. */ 235 private final PackageConflicts _conflicts = new PackageConflicts(); 236 237 /** A list of packages this package replaces. */ 238 private final PackageReplacements _replacements = new PackageReplacements(); 239 240 /** Permissions to apply to paths contained within this package. */ 241 private final PermissionsMap _permissions = new PermissionsMap(); 242 243 /** The package maintainer, e.g. "Package maintainer <maintainer@corp.com>". */ 244 private final PackageMaintainer _maintainer; 245 246 /** A description for this package. */ 247 private final PackageDescription _description; 248 249 /** The maintainer scripts to run with this package. */ 250 private final Map<MaintainerScript.Type, MaintainerScript> _scripts = 251 new TreeMap<MaintainerScript.Type, MaintainerScript>(); 252 }