1 /** 2 * Copyright (c) 2013-2023, jcabi.com 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 1) Redistributions of source code must retain the above 8 * copyright notice, this list of conditions and the following 9 * disclaimer. 2) Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 3) Neither the name of the jcabi.com nor 13 * the names of its contributors may be used to endorse or promote 14 * products derived from this software without specific prior written 15 * permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 19 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 * OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package com.jcabi.github; 31 32 import com.jcabi.aspects.Immutable; 33 import com.jcabi.aspects.Loggable; 34 import java.io.IOException; 35 import lombok.EqualsAndHashCode; 36 import lombok.ToString; 37 38 /** 39 * Github Releases. 40 * 41 * @author Paul Polishchuk (ppol@ua.fm) 42 * @version $Id: e2ab44836e23a8d14c817cea8bffb139fba4a047 $ 43 * @since 0.8 44 */ 45 @Immutable 46 public interface Releases { 47 /** 48 * Owner of them. 49 * @return Repo 50 */ 51 Repo repo(); 52 53 /** 54 * Iterate them all. 55 * @return Iterator of releases 56 * @see <a href="https://developer.github.com/v3/repos/releases/#list">List</a> 57 */ 58 Iterable<Release> iterate(); 59 60 /** 61 * Get a single release. 62 * @param number Release id 63 * @return Release 64 * @see <a href="https://developer.github.com/v3/repos/releases/#get-a-single-release">Get a single release</a> 65 */ 66 Release get(int number); 67 68 /** 69 * Create new release. 70 * @param tag The name of the tag 71 * @return Release just created 72 * @throws java.io.IOException If there is any I/O problem 73 * @see <a href="https://developer.github.com/v3/repos/releases/#create-a-release">Create an Release</a> 74 */ 75 Release create( 76 String tag) 77 throws IOException; 78 79 /** 80 * Remove a release. 81 * 82 * @param number ID of the release to remove. 83 * @throws IOException If an IO problem occurs. 84 * @see <a href="https://developer.github.com/v3/repos/releases/#delete-a-release">Delete a release.</a> 85 */ 86 void remove(int number) throws IOException; 87 88 /** 89 * Smart releases. 90 * @since 0.17 91 */ 92 @Immutable 93 @ToString 94 @Loggable(Loggable.DEBUG) 95 @EqualsAndHashCode(of = "releases") 96 final class Smart implements Releases { 97 /** 98 * Encapsulated releases. 99 */ 100 private final transient Releases releases; 101 102 /** 103 * Public CTOR. 104 * @param original Original releases 105 */ 106 public Smart( 107 final Releases original 108 ) { 109 this.releases = original; 110 } 111 @Override 112 public Repo repo() { 113 return this.releases.repo(); 114 } 115 @Override 116 public Iterable<Release> iterate() { 117 return this.releases.iterate(); 118 } 119 @Override 120 public Release get(final int number) { 121 return this.releases.get(number); 122 } 123 @Override 124 public Release create(final String tag) throws IOException { 125 return this.releases.create(tag); 126 } 127 @Override 128 public void remove(final int number) throws IOException { 129 this.releases.remove(number); 130 } 131 /** 132 * This release exists by the tag. 133 * @param tag The tag 134 * @return TRUE if it already exists 135 * @throws IOException If fails 136 */ 137 public boolean exists(final String tag) throws IOException { 138 boolean exists = false; 139 final Iterable<Release.Smart> rels = new Smarts<>( 140 this.iterate() 141 ); 142 for (final Release.Smart rel : rels) { 143 if (rel.tag().equals(tag)) { 144 exists = true; 145 break; 146 } 147 } 148 return exists; 149 } 150 /** 151 * Find release by the tag (runtime exception if not found). 152 * @param tag The tag 153 * @return Release found 154 * @throws IOException If fails 155 */ 156 public Release find(final String tag) throws IOException { 157 Release found = null; 158 final Iterable<Release.Smart> rels = new Smarts<>( 159 this.iterate() 160 ); 161 for (final Release.Smart rel : rels) { 162 if (rel.tag().equals(tag)) { 163 found = rel; 164 break; 165 } 166 } 167 if (found == null) { 168 throw new IllegalArgumentException( 169 String.format("release not found by tag '%s'", tag) 170 ); 171 } 172 return found; 173 } 174 } 175 }