Java tutorial
/**************************************************************** * 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.james.jmap; import java.io.IOException; import java.util.EnumSet; import java.util.List; import java.util.Optional; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.io.FileUtils; import org.apache.james.filesystem.api.FileSystem; import org.apache.james.jmap.mailet.VacationMailet; import org.apache.james.jmap.methods.RequestHandler; import org.apache.james.jmap.utils.HtmlTextExtractor; import org.apache.james.jmap.utils.MailboxBasedHtmlTextExtractor; import org.apache.james.jmap.utils.SystemMailboxesProvider; import org.apache.james.jmap.utils.SystemMailboxesProviderImpl; import org.apache.james.lifecycle.api.Configurable; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxManager.SearchCapabilities; import org.apache.james.mailetcontainer.impl.MatcherMailetPair; import org.apache.james.modules.server.CamelMailetContainerModule; import org.apache.james.transport.mailets.RemoveMimeHeader; import org.apache.james.transport.matchers.All; import org.apache.james.transport.matchers.RecipientIsLocal; import org.apache.james.utils.ConfigurationPerformer; import org.apache.james.utils.PropertiesProvider; import com.github.fge.lambdas.Throwing; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.inject.AbstractModule; import com.google.inject.Inject; import com.google.inject.Provides; import com.google.inject.Scopes; import com.google.inject.Singleton; import com.google.inject.multibindings.Multibinder; public class JMAPModule extends AbstractModule { private static final int DEFAULT_JMAP_PORT = 80; @Override protected void configure() { install(new JMAPCommonModule()); install(new MethodsModule()); bind(JMAPServer.class).in(Scopes.SINGLETON); bind(RequestHandler.class).in(Scopes.SINGLETON); bind(UploadHandler.class).in(Scopes.SINGLETON); bind(MailboxBasedHtmlTextExtractor.class).in(Scopes.SINGLETON); bind(HtmlTextExtractor.class).to(MailboxBasedHtmlTextExtractor.class); Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding() .to(RequiredCapabilitiesPrecondition.class); Multibinder<CamelMailetContainerModule.TransportProcessorCheck> transportProcessorChecks = Multibinder .newSetBinder(binder(), CamelMailetContainerModule.TransportProcessorCheck.class); transportProcessorChecks.addBinding().to(VacationMailetCheck.class); transportProcessorChecks.addBinding().to(BccMailetCheck.class); bind(SystemMailboxesProvider.class).to(SystemMailboxesProviderImpl.class); } @Provides @Singleton JMAPConfiguration provideConfiguration(PropertiesProvider propertiesProvider, FileSystem fileSystem) throws ConfigurationException, IOException { PropertiesConfiguration configuration = propertiesProvider.getConfiguration("jmap"); return JMAPConfiguration.builder().keystore(configuration.getString("tls.keystoreURL")) .secret(configuration.getString("tls.secret")) .jwtPublicKeyPem(loadPublicKey(fileSystem, Optional.ofNullable(configuration.getString("jwt.publickeypem.url")))) .port(configuration.getInt("jmap.port", DEFAULT_JMAP_PORT)).build(); } private Optional<String> loadPublicKey(FileSystem fileSystem, Optional<String> jwtPublickeyPemUrl) { return jwtPublickeyPemUrl .map(Throwing.function(url -> FileUtils.readFileToString(fileSystem.getFile(url)))); } @Singleton public static class RequiredCapabilitiesPrecondition implements ConfigurationPerformer { private final MailboxManager mailboxManager; @Inject public RequiredCapabilitiesPrecondition(MailboxManager mailboxManager) { this.mailboxManager = mailboxManager; } @Override public void initModule() { Preconditions.checkArgument(mailboxManager.hasCapability(MailboxManager.MailboxCapabilities.Move), "MOVE support in MailboxManager is required by JMAP Module"); Preconditions.checkArgument( mailboxManager.getSupportedMessageCapabilities() .contains(MailboxManager.MessageCapabilities.Attachment), "Attachment support in MailboxManager is required by JMAP Module"); EnumSet<SearchCapabilities> searchCapabilities = mailboxManager.getSupportedSearchCapabilities(); Preconditions.checkArgument( searchCapabilities.contains(MailboxManager.SearchCapabilities.MultimailboxSearch), "Multimailbox search in MailboxManager is required by JMAP Module"); Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.Text), "Text support in MailboxManager is required by JMAP Module"); } @Override public List<Class<? extends Configurable>> forClasses() { return ImmutableList.of(); } } public static class VacationMailetCheck implements CamelMailetContainerModule.TransportProcessorCheck { @Override public void check(List<MatcherMailetPair> pairs) throws ConfigurationException { Preconditions.checkNotNull(pairs); pairs.stream().filter(pair -> pair.getMailet().getClass().equals(VacationMailet.class)) .filter(pair -> pair.getMatcher().getClass().equals(RecipientIsLocal.class)).findAny() .orElseThrow(() -> new ConfigurationException("Missing " + VacationMailet.class.getName() + " in mailets configuration (mailetcontainer -> processors -> transport)")); } } public static class BccMailetCheck implements CamelMailetContainerModule.TransportProcessorCheck { @Override public void check(List<MatcherMailetPair> pairs) throws ConfigurationException { Preconditions.checkNotNull(pairs); pairs.stream().filter(pair -> pair.getMailet().getClass().equals(RemoveMimeHeader.class)) .filter(pair -> pair.getMatcher().getClass().equals(All.class)) .filter(pair -> pair.getMailet().getMailetConfig().getInitParameter("name").equals("bcc")) .findAny().orElseThrow(() -> new ConfigurationException( "Missing RemoveMimeHeader in mailets configuration (mailetcontainer -> processors -> transport). Should be configured to remove Bcc header")); } } }