| /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| ~ Licensed to the Apache Software Foundation (ASF) under one |
| ~ or more contributor license agreements. See the NOTICE file |
| ~ distributed with this work for additional information |
| ~ regarding copyright ownership. The ASF licenses this file |
| ~ to you 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 org.apache.sling.cli.impl.people; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.text.Collator; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Locale; |
| import java.util.Set; |
| |
| import org.apache.http.client.methods.CloseableHttpResponse; |
| import org.apache.http.client.methods.HttpGet; |
| import org.apache.http.impl.client.CloseableHttpClient; |
| import org.apache.http.impl.client.HttpClients; |
| import org.apache.sling.cli.impl.CredentialsService; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.osgi.service.component.annotations.Component; |
| import org.osgi.service.component.annotations.Reference; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.google.gson.JsonElement; |
| import com.google.gson.JsonObject; |
| import com.google.gson.JsonParser; |
| |
| @Component(service = MembersFinder.class) |
| public class MembersFinder { |
| |
| private static final Logger LOGGER = LoggerFactory.getLogger(MembersFinder.class); |
| private static final String PEOPLE_ENDPOINT = "https://whimsy.apache.org/public/public_ldap_people.json"; |
| private static final String PROJECTS_ENDPOINT = "https://whimsy.apache.org/public/public_ldap_projects.json"; |
| private static final int STALENESS_IN_HOURS = 3; |
| private Set<Member> members = Collections.emptySet(); |
| private long lastCheck = 0; |
| |
| @Reference |
| private CredentialsService credentialsService; |
| |
| public synchronized Set<Member> findMembers() { |
| final Set<Member> membersReplacementSet = new HashSet<>(); |
| if (lastCheck == 0 || System.currentTimeMillis() > lastCheck + STALENESS_IN_HOURS * 3600 * 1000) { |
| lastCheck = System.currentTimeMillis(); |
| try (CloseableHttpClient client = HttpClients.createDefault()) { |
| JsonParser parser = new JsonParser(); |
| Set<String> memberIds; |
| Set<String> pmcMemberIds; |
| try (CloseableHttpResponse response = client.execute(new HttpGet(PROJECTS_ENDPOINT))) { |
| try (InputStream content = response.getEntity().getContent(); |
| InputStreamReader reader = new InputStreamReader(content)) { |
| if (response.getStatusLine().getStatusCode() != 200) { |
| throw new IOException("Status line : " + response.getStatusLine()); |
| } |
| JsonElement jsonElement = parser.parse(reader); |
| JsonObject json = jsonElement.getAsJsonObject(); |
| JsonObject sling = json.get("projects").getAsJsonObject().get("sling").getAsJsonObject(); |
| memberIds = new HashSet<>(); |
| pmcMemberIds = new HashSet<>(); |
| for (JsonElement member : sling.getAsJsonArray("members")) { |
| memberIds.add(member.getAsString()); |
| } |
| for (JsonElement pmcMember : sling.getAsJsonArray("owners")) { |
| pmcMemberIds.add(pmcMember.getAsString()); |
| } |
| } |
| } |
| try (CloseableHttpResponse response = client.execute(new HttpGet(PEOPLE_ENDPOINT))) { |
| try (InputStream content = response.getEntity().getContent(); |
| InputStreamReader reader = new InputStreamReader(content)) { |
| if (response.getStatusLine().getStatusCode() != 200) { |
| throw new IOException("Status line : " + response.getStatusLine()); |
| } |
| JsonElement jsonElement = parser.parse(reader); |
| JsonObject json = jsonElement.getAsJsonObject(); |
| JsonObject people = json.get("people").getAsJsonObject(); |
| for (String id : memberIds) { |
| String name = people.get(id).getAsJsonObject().get("name").getAsString(); |
| membersReplacementSet.add(new Member(id, name, pmcMemberIds.contains(id))); |
| } |
| |
| } |
| } |
| members = Collections.unmodifiableSet(membersReplacementSet); |
| } catch (IOException e) { |
| LOGGER.error("Unable to retrieve Apache Sling project members.", e); |
| } |
| } |
| return members; |
| } |
| |
| public Member findById(String id) { |
| for (Member member : findMembers()) { |
| if (id.equals(member.getId())) { |
| return member; |
| } |
| } |
| return null; |
| } |
| |
| public Member findByNameOrEmail(@Nullable String name, @NotNull String email) { |
| Collator collator = Collator.getInstance(Locale.US); |
| collator.setDecomposition(Collator.NO_DECOMPOSITION); |
| for (Member member : findMembers()) { |
| if (email.equals(member.getEmail()) || (name != null && collator.compare(name, member.getName()) == 0)) { |
| return member; |
| } |
| } |
| return null; |
| } |
| |
| public Member getCurrentMember() { |
| return findById(credentialsService.getAsfCredentials().getUsername()); |
| } |
| |
| } |