http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtil.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtil.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtil.java new file mode 100644 index 0000000..7abe76d --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtil.java @@ -0,0 +1,36 @@ +/* + * 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.syncope.core.persistence.api.entity.task; + +import org.apache.syncope.common.lib.to.AbstractTaskTO; +import org.apache.syncope.common.lib.types.TaskType; + +public interface TaskUtil { + + TaskType getType(); + + <T extends Task> T newTask(); + + <T extends AbstractTaskTO> T newTaskTO(); + + <T extends Task> Class<T> taskClass(); + + <T extends AbstractTaskTO> Class<T> taskTOClass(); + +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtilFactory.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtilFactory.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtilFactory.java new file mode 100644 index 0000000..6bc172d --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtilFactory.java @@ -0,0 +1,33 @@ +/* + * 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.syncope.core.persistence.api.entity.task; + +import org.apache.syncope.common.lib.to.AbstractTaskTO; +import org.apache.syncope.common.lib.types.TaskType; + +public interface TaskUtilFactory { + + TaskUtil getInstance(TaskType type); + + TaskUtil getInstance(Task task); + + TaskUtil getInstance(Class<? extends AbstractTaskTO> taskClass); + + TaskUtil getInstance(AbstractTaskTO taskTO); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/SecurityQuestion.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/SecurityQuestion.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/SecurityQuestion.java new file mode 100644 index 0000000..4b49e76 --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/SecurityQuestion.java @@ -0,0 +1,28 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.Entity; + +public interface SecurityQuestion extends Entity<Long> { + + String getContent(); + + void setContent(String content); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java new file mode 100644 index 0000000..9c88907 --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java @@ -0,0 +1,31 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.DerAttr; + +public interface UDerAttr extends DerAttr { + + @Override + User getOwner(); + + @Override + UDerSchema getSchema(); + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerSchema.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerSchema.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerSchema.java new file mode 100644 index 0000000..f9c75f0 --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerSchema.java @@ -0,0 +1,25 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.DerSchema; + +public interface UDerSchema extends DerSchema { + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java new file mode 100644 index 0000000..f99b4bc --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java @@ -0,0 +1,28 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.Mapping; + +public interface UMapping extends Mapping<UMappingItem> { + + UMappingItem getPasswordItem(); + + boolean setPasswordItem(UMappingItem item); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java new file mode 100644 index 0000000..a21aa0a --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java @@ -0,0 +1,29 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.Mapping; +import org.apache.syncope.core.persistence.api.entity.MappingItem; + +public interface UMappingItem extends MappingItem { + + @Override + Mapping<UMappingItem> getMapping(); + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java new file mode 100644 index 0000000..fa861d9 --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java @@ -0,0 +1,38 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import java.util.List; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; + +public interface UPlainAttr extends PlainAttr { + + @Override + User getOwner(); + + @Override + UPlainSchema getSchema(); + + @Override + List<? extends UPlainAttrValue> getValues(); + + @Override + UPlainAttrUniqueValue getUniqueValue(); + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java new file mode 100644 index 0000000..db3ff47 --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java @@ -0,0 +1,31 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; + +public interface UPlainAttrUniqueValue extends PlainAttrUniqueValue { + + @Override + UPlainAttr getAttr(); + + @Override + UPlainSchema getSchema(); + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrValue.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrValue.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrValue.java new file mode 100644 index 0000000..4a54e1a --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrValue.java @@ -0,0 +1,28 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; + +public interface UPlainAttrValue extends PlainAttrValue { + + @Override + UPlainAttr getAttr(); + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainSchema.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainSchema.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainSchema.java new file mode 100644 index 0000000..b9126af --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainSchema.java @@ -0,0 +1,25 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.PlainSchema; + +public interface UPlainSchema extends PlainSchema { + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java new file mode 100644 index 0000000..12f1b5e --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java @@ -0,0 +1,31 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.VirAttr; + +public interface UVirAttr extends VirAttr { + + @Override + User getOwner(); + + @Override + UVirSchema getSchema(); + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirSchema.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirSchema.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirSchema.java new file mode 100644 index 0000000..3768d6f --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirSchema.java @@ -0,0 +1,25 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.VirSchema; + +public interface UVirSchema extends VirSchema { + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java new file mode 100644 index 0000000..66898e4 --- /dev/null +++ b/syncope620/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java @@ -0,0 +1,150 @@ +/* + * 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.syncope.core.persistence.api.entity.user; + +import java.util.Date; +import java.util.List; +import java.util.Set; +import org.apache.syncope.common.lib.types.CipherAlgorithm; +import org.apache.syncope.core.persistence.api.entity.ExternalResource; +import org.apache.syncope.core.persistence.api.entity.Subject; +import org.apache.syncope.core.persistence.api.entity.membership.Membership; +import org.apache.syncope.core.persistence.api.entity.role.Role; + +public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> { + + boolean addMembership(Membership membership); + + boolean canDecodePassword(); + + boolean checkToken(String token); + + void generateToken(int tokenLength, int tokenExpireTime); + + Date getChangePwdDate(); + + CipherAlgorithm getCipherAlgorithm(); + + String getClearPassword(); + + Integer getFailedLogins(); + + Date getLastLoginDate(); + + Membership getMembership(Long roleKey); + + List<? extends Membership> getMemberships(); + + Set<? extends ExternalResource> getOwnResources(); + + String getPassword(); + + List<String> getPasswordHistory(); + + Set<Long> getRoleKeys(); + + List<Role> getRoles(); + + String getSecurityAnswer(); + + SecurityQuestion getSecurityQuestion(); + + String getStatus(); + + String getToken(); + + Date getTokenExpireTime(); + + String getUsername(); + + String getWorkflowId(); + + boolean hasTokenExpired(); + + Boolean isSuspended(); + + void removeClearPassword(); + + boolean removeMembership(Membership membership); + + void removeToken(); + + void setChangePwdDate(Date changePwdDate); + + void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm); + + void setEncodedPassword(String password, CipherAlgorithm cipherAlgoritm); + + void setFailedLogins(Integer failedLogins); + + void setLastLoginDate(Date lastLoginDate); + + void setPassword(String password, CipherAlgorithm cipherAlgoritm); + + void setSecurityAnswer(String securityAnswer); + + void setSecurityQuestion(SecurityQuestion securityQuestion); + + void setStatus(String status); + + void setSuspended(Boolean suspended); + + void setUsername(String username); + + void setWorkflowId(String workflowId); + + boolean verifyPasswordHistory(String password, int size); + + @Override + boolean addPlainAttr(UPlainAttr attr); + + @Override + boolean removePlainAttr(UPlainAttr attr); + + @Override + boolean addDerAttr(UDerAttr attr); + + @Override + boolean removeDerAttr(UDerAttr derAttr); + + @Override + boolean addVirAttr(UVirAttr attr); + + @Override + boolean removeVirAttr(UVirAttr virAttr); + + @Override + UPlainAttr getPlainAttr(String plainSchemaName); + + @Override + List<? extends UPlainAttr> getPlainAttrs(); + + @Override + UDerAttr getDerAttr(String derSchemaName); + + @Override + List<? extends UDerAttr> getDerAttrs(); + + @Override + UVirAttr getVirAttr(String virSchemaName); + + @Override + List<? extends UVirAttr> getVirAttrs(); + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/pom.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/pom.xml b/syncope620/core/persistence-jpa/pom.xml new file mode 100644 index 0000000..bd9ce25 --- /dev/null +++ b/syncope620/core/persistence-jpa/pom.xml @@ -0,0 +1,222 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.syncope</groupId> + <artifactId>syncope-core</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <name>Apache Syncope Core Persistence JPA</name> + <description>Apache Syncope Core Persistence JPA</description> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-persistence-jpa</artifactId> + <packaging>jar</packaging> + + <properties> + <rootpom.basedir>${basedir}/../..</rootpom.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-jpa_2.0_spec</artifactId> + </dependency> + <dependency> + <groupId>javax.el</groupId> + <artifactId>javax.el-api</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa-jdbc</artifactId> + </dependency> + <dependency> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa-persistence-jdbc</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-dbcp2</artifactId> + </dependency> + + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-validator</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-tx</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-jdbc</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-orm</artifactId> + </dependency> + + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-workflow-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-misc</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- TEST --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <version>${slf4j.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa-maven-plugin</artifactId> + <inherited>true</inherited> + <dependencies> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>${h2.version}</version> + </dependency> + </dependencies> + <configuration> + <persistenceXmlFile>${project.basedir}/src/test/resources/META-INF/persistence-enhance.xml</persistenceXmlFile> + <includes>org/apache/syncope/core/persistence/jpa/entity/**/*.class</includes> + <connectionDriverName>org.springframework.jdbc.datasource.DriverManagerDataSource</connectionDriverName> + <connectionProperties> + driverClassName=org.h2.Driver, + url=jdbc:h2:mem:syncopedb + username=sa, + password= + </connectionProperties> + </configuration> + <executions> + <execution> + <id>enhancer</id> + <phase>process-classes</phase> + <goals> + <goal>enhance</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + </plugin> + </plugins> + + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> + <testResources> + <testResource> + <directory>src/test/resources</directory> + <filtering>true</filtering> + </testResource> + </testResources> + </build> + + <profiles> + <profile> + <id>sqlgen</id> + + <properties> + <skipTests>true</skipTests> + </properties> + + <build> + <defaultGoal>clean verify</defaultGoal> + + <plugins> + <plugin> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa-maven-plugin</artifactId> + <inherited>true</inherited> + <executions> + <execution> + <id>sqlgenr</id> + <phase>process-classes</phase> + <goals> + <goal>sql</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + </profile> + </profiles> + +</project> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/AbstractValidator.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/AbstractValidator.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/AbstractValidator.java new file mode 100644 index 0000000..27e2dc8 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/AbstractValidator.java @@ -0,0 +1,54 @@ +/* + * 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.syncope.core.persistence.jpa.attrvalue.validation; + +import java.io.Serializable; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; +import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException; +import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractValidator implements Validator, Serializable { + + private static final long serialVersionUID = -5439345166669502493L; + + /* + * Logger + */ + protected static final Logger LOG = LoggerFactory.getLogger(AbstractValidator.class); + + protected final PlainSchema schema; + + public AbstractValidator(final PlainSchema schema) { + this.schema = schema; + } + + @Override + public void validate(String value, PlainAttrValue attrValue) + throws ParsingValidationException, InvalidPlainAttrValueException { + + attrValue.parseValue(schema, value); + doValidate(attrValue); + } + + protected abstract void doValidate(PlainAttrValue attrValue) throws InvalidPlainAttrValueException; +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/AlwaysTrueValidator.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/AlwaysTrueValidator.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/AlwaysTrueValidator.java new file mode 100644 index 0000000..25bc68e --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/AlwaysTrueValidator.java @@ -0,0 +1,40 @@ +/* + * 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.syncope.core.persistence.jpa.attrvalue.validation; + +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; + +public class AlwaysTrueValidator extends AbstractValidator { + + private static final long serialVersionUID = 872107345555773183L; + + public AlwaysTrueValidator(final PlainSchema schema) { + super(schema); + } + + @Override + protected void doValidate(final PlainAttrValue attrValue) throws InvalidPlainAttrValueException { + Boolean value = attrValue.getValue(); + if (!value) { + throw new InvalidPlainAttrValueException("This attribute must be set to \"true\""); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/BasicValidator.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/BasicValidator.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/BasicValidator.java new file mode 100644 index 0000000..0676461 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/BasicValidator.java @@ -0,0 +1,54 @@ +/* + * 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.syncope.core.persistence.jpa.attrvalue.validation; + +import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.common.lib.types.AttrSchemaType; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; + +public class BasicValidator extends AbstractValidator { + + private static final long serialVersionUID = -2606728447694223607L; + + public BasicValidator(final PlainSchema schema) { + super(schema); + } + + @Override + protected void doValidate(final PlainAttrValue attrValue) throws InvalidPlainAttrValueException { + if (AttrSchemaType.Enum == schema.getType()) { + final String[] enumeration = schema.getEnumerationValues().split(SyncopeConstants.ENUM_VALUES_SEPARATOR); + final String value = attrValue.getStringValue(); + + boolean found = false; + for (int i = 0; i < enumeration.length && !found; i++) { + if (enumeration[i].trim().equals(value)) { + found = true; + } + } + + if (!found) { + throw new InvalidPlainAttrValueException( + "'" + value + "' is not one of: " + schema.getEnumerationValues()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/EmailAddressValidator.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/EmailAddressValidator.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/EmailAddressValidator.java new file mode 100644 index 0000000..b78e86c --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/EmailAddressValidator.java @@ -0,0 +1,42 @@ +/* + * 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.syncope.core.persistence.jpa.attrvalue.validation; + +import java.util.regex.Matcher; +import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; + +public class EmailAddressValidator extends AbstractValidator { + + private static final long serialVersionUID = 792457177290331518L; + + public EmailAddressValidator(final PlainSchema schema) { + super(schema); + } + + @Override + protected void doValidate(final PlainAttrValue attrValue) throws InvalidPlainAttrValueException { + Matcher matcher = SyncopeConstants.EMAIL_PATTERN.matcher(attrValue.<CharSequence>getValue()); + if (!matcher.matches()) { + throw new InvalidPlainAttrValueException("\"" + attrValue.getValue() + "\" is not a valid email address"); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java new file mode 100644 index 0000000..3bec6b1 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java @@ -0,0 +1,88 @@ +/* + * 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.syncope.core.persistence.jpa.content; + +import java.io.IOException; +import java.util.Properties; +import javax.annotation.Resource; +import javax.sql.DataSource; +import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.support.PropertiesLoaderUtils; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; + +public abstract class AbstractContentDealer { + + protected static final Logger LOG = LoggerFactory.getLogger(AbstractContentDealer.class); + + protected static final String ROOT_ELEMENT = "dataset"; + + @Resource(name = "database.schema") + protected String dbSchema; + + @Resource(name = "indexesXML") + private ResourceWithFallbackLoader indexesXML; + + @Resource(name = "viewsXML") + private ResourceWithFallbackLoader viewsXML; + + @Autowired + protected DataSource dataSource; + + protected void createIndexes() throws IOException { + LOG.debug("Creating indexes"); + + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + Properties indexes = PropertiesLoaderUtils.loadProperties(indexesXML.getResource()); + for (String idx : indexes.stringPropertyNames()) { + LOG.debug("Creating index {}", indexes.get(idx).toString()); + + try { + jdbcTemplate.execute(indexes.get(idx).toString()); + } catch (DataAccessException e) { + LOG.error("Could not create index ", e); + } + } + + LOG.debug("Indexes created"); + } + + protected void createViews() throws IOException { + LOG.debug("Creating views"); + + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + Properties views = PropertiesLoaderUtils.loadProperties(viewsXML.getResource()); + for (String idx : views.stringPropertyNames()) { + LOG.debug("Creating view {}", views.get(idx).toString()); + + try { + jdbcTemplate.execute(views.get(idx).toString().replaceAll("\\n", " ")); + } catch (DataAccessException e) { + LOG.error("Could not create view ", e); + } + } + + LOG.debug("Views created"); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java new file mode 100644 index 0000000..0361773 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java @@ -0,0 +1,201 @@ +/* + * 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.syncope.core.persistence.jpa.content; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; +import javax.sql.DataSource; +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; +import org.apache.syncope.core.misc.DataFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * SAX handler for generating SQL INSERT statements out of given XML file. + */ +class ContentLoaderHandler extends DefaultHandler { + + private static final Logger LOG = LoggerFactory.getLogger(ContentLoaderHandler.class); + + private final DataSource dataSource; + + private final String rootElement; + + public ContentLoaderHandler(final DataSource dataSource, final String rootElement) { + this.dataSource = dataSource; + this.rootElement = rootElement; + } + + private Object[] getParameters(final String tableName, final Attributes attrs) { + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + Map<String, Integer> colTypes = jdbcTemplate.query("SELECT * FROM " + tableName + " WHERE 0=1", + new ResultSetExtractor<Map<String, Integer>>() { + + @Override + public Map<String, Integer> extractData(final ResultSet rs) + throws SQLException, DataAccessException { + + Map<String, Integer> colTypes = new HashMap<>(); + for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { + colTypes.put(rs.getMetaData().getColumnName(i).toUpperCase(), + rs.getMetaData().getColumnType(i)); + } + return colTypes; + } + }); + + Object[] parameters = new Object[attrs.getLength()]; + for (int i = 0; i < attrs.getLength(); i++) { + Integer colType = colTypes.get(attrs.getQName(i).toUpperCase()); + if (colType == null) { + LOG.warn("No column type found for {}", attrs.getQName(i).toUpperCase()); + colType = Types.VARCHAR; + } + + switch (colType) { + case Types.INTEGER: + case Types.TINYINT: + case Types.SMALLINT: + try { + parameters[i] = Integer.valueOf(attrs.getValue(i)); + } catch (NumberFormatException e) { + LOG.error("Unparsable Integer '{}'", attrs.getValue(i)); + parameters[i] = attrs.getValue(i); + } + break; + + case Types.NUMERIC: + case Types.DECIMAL: + case Types.BIGINT: + try { + parameters[i] = Long.valueOf(attrs.getValue(i)); + } catch (NumberFormatException e) { + LOG.error("Unparsable Long '{}'", attrs.getValue(i)); + parameters[i] = attrs.getValue(i); + } + break; + + case Types.DOUBLE: + try { + parameters[i] = Double.valueOf(attrs.getValue(i)); + } catch (NumberFormatException e) { + LOG.error("Unparsable Double '{}'", attrs.getValue(i)); + parameters[i] = attrs.getValue(i); + } + break; + + case Types.REAL: + case Types.FLOAT: + try { + parameters[i] = Float.valueOf(attrs.getValue(i)); + } catch (NumberFormatException e) { + LOG.error("Unparsable Float '{}'", attrs.getValue(i)); + parameters[i] = attrs.getValue(i); + } + break; + + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + try { + parameters[i] = DataFormat.parseDate(attrs.getValue(i)); + } catch (ParseException e) { + LOG.error("Unparsable Date '{}'", attrs.getValue(i)); + parameters[i] = attrs.getValue(i); + } + break; + + case Types.BIT: + case Types.BOOLEAN: + parameters[i] = "1".equals(attrs.getValue(i)) ? Boolean.TRUE : Boolean.FALSE; + break; + + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + try { + parameters[i] = Hex.decodeHex(attrs.getValue(i).toCharArray()); + } catch (DecoderException | IllegalArgumentException e) { + parameters[i] = attrs.getValue(i); + } + break; + + case Types.BLOB: + try { + parameters[i] = Hex.decodeHex(attrs.getValue(i).toCharArray()); + } catch (DecoderException | IllegalArgumentException e) { + LOG.warn("Error decoding hex string to specify a blob parameter", e); + parameters[i] = attrs.getValue(i); + } catch (Exception e) { + LOG.warn("Error creating a new blob parameter", e); + } + break; + + default: + parameters[i] = attrs.getValue(i); + } + } + + return parameters; + } + + @Override + public void startElement(final String uri, final String localName, final String qName, final Attributes atts) + throws SAXException { + + // skip root element + if (rootElement.equals(qName)) { + return; + } + + StringBuilder query = new StringBuilder("INSERT INTO ").append(qName).append('('); + + StringBuilder values = new StringBuilder(); + + for (int i = 0; i < atts.getLength(); i++) { + query.append(atts.getQName(i)); + values.append('?'); + if (i < atts.getLength() - 1) { + query.append(','); + values.append(','); + } + } + query.append(") VALUES (").append(values).append(')'); + + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + try { + jdbcTemplate.update(query.toString(), getParameters(qName, atts)); + } catch (DataAccessException e) { + LOG.error("While trying to perform {}", query, e); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java new file mode 100644 index 0000000..95b7da5 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java @@ -0,0 +1,106 @@ +/* + * 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.syncope.core.persistence.jpa.content; + +import java.util.HashSet; +import java.util.Set; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +class MultiParentNode<T> { + + private final T object; + + private Set<MultiParentNode<T>> children; + + private int level = 0; + + private boolean exploited = false; + + public MultiParentNode(final T object) { + this.object = object; + children = new HashSet<MultiParentNode<T>>(); + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + boolean isExploited() { + return exploited; + } + + void setExploited(boolean exploited) { + this.exploited = exploited; + } + + public T getObject() { + return object; + } + + public boolean isParent(final MultiParentNode<T> child) { + return children.contains(child); + } + + public boolean isChild(final MultiParentNode<T> parent) { + return parent.isParent(this); + } + + public Set<MultiParentNode<T>> getChildren() { + return children; + } + + public void addParent(final MultiParentNode<T> parent) { + if (parent != null) { + parent.children.add(this); + } + } + + public void removeParent(final MultiParentNode<T> parent) { + if (parent != null) { + parent.children.remove(this); + } + } + + public void addChild(final MultiParentNode<T> child) { + if (child != null) { + children.add(child); + } + } + + public void removeChild(final MultiParentNode<T> child) { + if (child != null) { + children.remove(child); + } + } + + @Override + public boolean equals(final Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNodeOp.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNodeOp.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNodeOp.java new file mode 100644 index 0000000..7c16b13 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNodeOp.java @@ -0,0 +1,49 @@ +/* + * 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.syncope.core.persistence.jpa.content; + +import java.util.Collection; +import java.util.Set; + +class MultiParentNodeOp { + + private MultiParentNodeOp() { + } + + public static <T> void traverseTree(final Set<MultiParentNode<T>> roots, final Collection<T> objects) { + for (MultiParentNode<T> root : roots) { + traverseTree(root, objects); + } + } + + public static <T> void traverseTree(final MultiParentNode<T> root, final Collection<T> objects) { + + root.setExploited(true); + + for (MultiParentNode<T> child : root.getChildren()) { + if (!child.isExploited()) { + traverseTree(child, objects); + } + } + + if (!objects.contains(root.getObject())) { + objects.add(root.getObject()); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java new file mode 100644 index 0000000..61535d6 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java @@ -0,0 +1,398 @@ +/* + * 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.syncope.core.persistence.jpa.content; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.sql.Blob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.core.misc.DataFormat; +import org.apache.syncope.core.persistence.api.content.ContentExporter; +import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec; +import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttr; +import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue; +import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr; +import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership; +import org.apache.syncope.core.persistence.jpa.entity.task.JPATaskExec; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; +import org.springframework.jdbc.datasource.DataSourceUtils; +import org.springframework.security.crypto.codec.Hex; +import org.springframework.stereotype.Component; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * Export internal storage content as XML. + */ +@Component +public class XMLContentExporter extends AbstractContentDealer implements ContentExporter { + + protected final static Set<String> TABLE_PREFIXES_TO_BE_EXCLUDED = + new HashSet<>(Arrays.asList(new String[] { + "QRTZ_", "LOGGING", JPAReportExec.TABLE, JPATaskExec.TABLE, + JPAUser.TABLE, JPAUPlainAttr.TABLE, JPAUPlainAttrValue.TABLE, JPAUPlainAttrUniqueValue.TABLE, + JPAUDerAttr.TABLE, JPAUVirAttr.TABLE, + JPAMembership.TABLE, JPAMPlainAttr.TABLE, JPAMPlainAttrValue.TABLE, JPAMPlainAttrUniqueValue.TABLE, + JPAMDerAttr.TABLE, JPAMVirAttr.TABLE + })); + + protected final static Set<String> TABLE_SUFFIXES_TO_BE_INCLUDED = + new HashSet<>(Arrays.asList(new String[] { "TEMPLATE" })); + + protected static final Map<String, String> TABLES_TO_BE_FILTERED = + Collections.singletonMap("TASK", "DTYPE <> 'PropagationTask'"); + + protected static final Map<String, Set<String>> COLUMNS_TO_BE_NULLIFIED = + Collections.singletonMap("SYNCOPEROLE", Collections.singleton("USEROWNER_ID")); + + private boolean isTableAllowed(final String tableName) { + boolean allowed = true; + for (String prefix : TABLE_PREFIXES_TO_BE_EXCLUDED) { + if (tableName.toUpperCase().startsWith(prefix)) { + for (String suffix : TABLE_SUFFIXES_TO_BE_INCLUDED) { + if (!tableName.toUpperCase().endsWith(suffix)) { + allowed = false; + } + } + } + } + return allowed; + } + + private List<String> sortByForeignKeys(final Connection conn, final Set<String> tableNames) + throws SQLException { + + Set<MultiParentNode<String>> roots = new HashSet<>(); + + final DatabaseMetaData meta = conn.getMetaData(); + + final Map<String, MultiParentNode<String>> exploited = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + final Set<String> pkTableNames = new HashSet<>(); + + for (String tableName : tableNames) { + MultiParentNode<String> node = exploited.get(tableName); + if (node == null) { + node = new MultiParentNode<>(tableName); + roots.add(node); + exploited.put(tableName, node); + } + + pkTableNames.clear(); + + ResultSet rs = null; + try { + rs = meta.getImportedKeys(conn.getCatalog(), dbSchema, tableName); + + // this is to avoid repetition + while (rs.next()) { + pkTableNames.add(rs.getString("PKTABLE_NAME")); + } + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + LOG.error("While closing tables result set", e); + } + } + } + + for (String pkTableName : pkTableNames) { + if (!tableName.equalsIgnoreCase(pkTableName)) { + MultiParentNode<String> pkNode = exploited.get(pkTableName); + if (pkNode == null) { + pkNode = new MultiParentNode<>(pkTableName); + roots.add(pkNode); + exploited.put(pkTableName, pkNode); + } + + pkNode.addChild(node); + + if (roots.contains(node)) { + roots.remove(node); + } + } + } + } + + final List<String> sortedTableNames = new ArrayList<>(tableNames.size()); + MultiParentNodeOp.traverseTree(roots, sortedTableNames); + + // remove from sortedTableNames any table possibly added during lookup + // but matching some item in this.tablePrefixesToBeExcluded + sortedTableNames.retainAll(tableNames); + + LOG.debug("Tables after retainAll {}", sortedTableNames); + + Collections.reverse(sortedTableNames); + + return sortedTableNames; + } + + private String getValues(final ResultSet rs, final String columnName, final Integer columnType) + throws SQLException { + + String res = null; + + try { + switch (columnType) { + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + final InputStream is = rs.getBinaryStream(columnName); + if (is != null) { + res = new String(Hex.encode(IOUtils.toByteArray(is))); + } + break; + + case Types.BLOB: + final Blob blob = rs.getBlob(columnName); + if (blob != null) { + res = new String(Hex.encode(IOUtils.toByteArray(blob.getBinaryStream()))); + } + break; + + case Types.BIT: + case Types.BOOLEAN: + if (rs.getBoolean(columnName)) { + res = "1"; + } else { + res = "0"; + } + break; + + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + final Timestamp timestamp = rs.getTimestamp(columnName); + if (timestamp != null) { + res = DataFormat.format(new Date(timestamp.getTime())); + } + break; + + default: + res = rs.getString(columnName); + } + } catch (IOException e) { + LOG.error("Error retrieving hexadecimal string", e); + } + + return res; + } + + private void doExportTable(final TransformerHandler handler, final Connection conn, final String tableName, + final String whereClause) throws SQLException, SAXException { + + LOG.debug("Export table {}", tableName); + + AttributesImpl attrs = new AttributesImpl(); + + PreparedStatement stmt = null; + ResultSet rs = null; + ResultSet pkeyRS = null; + try { + // ------------------------------------ + // retrieve primary keys to perform an ordered select + + final DatabaseMetaData meta = conn.getMetaData(); + pkeyRS = meta.getPrimaryKeys(null, null, tableName); + + final StringBuilder orderBy = new StringBuilder(); + + while (pkeyRS.next()) { + final String columnName = pkeyRS.getString("COLUMN_NAME"); + if (columnName != null) { + if (orderBy.length() > 0) { + orderBy.append(","); + } + + orderBy.append(columnName); + } + } + + // ------------------------------------ + StringBuilder query = new StringBuilder(); + query.append("SELECT * FROM ").append(tableName).append(" a"); + if (StringUtils.isNotBlank(whereClause)) { + query.append(" WHERE ").append(whereClause); + } + if (orderBy.length() > 0) { + query.append(" ORDER BY ").append(orderBy); + } + stmt = conn.prepareStatement(query.toString()); + + rs = stmt.executeQuery(); + while (rs.next()) { + attrs.clear(); + + final ResultSetMetaData rsMeta = rs.getMetaData(); + for (int i = 0; i < rsMeta.getColumnCount(); i++) { + final String columnName = rsMeta.getColumnName(i + 1); + final Integer columnType = rsMeta.getColumnType(i + 1); + + // Retrieve value taking care of binary values. + String value = getValues(rs, columnName, columnType); + if (value != null && (!COLUMNS_TO_BE_NULLIFIED.containsKey(tableName) + || !COLUMNS_TO_BE_NULLIFIED.get(tableName).contains(columnName))) { + + attrs.addAttribute("", "", columnName, "CDATA", value); + } + } + + handler.startElement("", "", tableName, attrs); + handler.endElement("", "", tableName); + + LOG.debug("Add record {}", attrs); + } + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + LOG.error("While closing result set", e); + } + } + if (pkeyRS != null) { + try { + pkeyRS.close(); + } catch (SQLException e) { + LOG.error("While closing result set", e); + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + LOG.error("While closing result set", e); + } + } + } + } + + @Override + public void export(final OutputStream os, final String uwfPrefix, String rwfPrefix) + throws SAXException, TransformerConfigurationException { + + if (StringUtils.isNotBlank(uwfPrefix)) { + TABLE_PREFIXES_TO_BE_EXCLUDED.add(uwfPrefix); + } + if (StringUtils.isNotBlank(rwfPrefix)) { + TABLE_PREFIXES_TO_BE_EXCLUDED.add(rwfPrefix); + } + + StreamResult streamResult = new StreamResult(os); + final SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); + + TransformerHandler handler = transformerFactory.newTransformerHandler(); + Transformer serializer = handler.getTransformer(); + serializer.setOutputProperty(OutputKeys.ENCODING, SyncopeConstants.DEFAULT_ENCODING); + serializer.setOutputProperty(OutputKeys.INDENT, "yes"); + handler.setResult(streamResult); + handler.startDocument(); + handler.startElement("", "", ROOT_ELEMENT, new AttributesImpl()); + + Connection conn = null; + ResultSet rs = null; + try { + conn = DataSourceUtils.getConnection(dataSource); + final DatabaseMetaData meta = conn.getMetaData(); + + rs = meta.getTables(null, StringUtils.isBlank(dbSchema) ? null : dbSchema, null, new String[] { "TABLE" }); + + final Set<String> tableNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + + while (rs.next()) { + String tableName = rs.getString("TABLE_NAME"); + LOG.debug("Found table {}", tableName); + if (isTableAllowed(tableName)) { + tableNames.add(tableName); + } + } + + LOG.debug("Tables to be exported {}", tableNames); + + // then sort tables based on foreign keys and dump + for (String tableName : sortByForeignKeys(conn, tableNames)) { + try { + doExportTable(handler, conn, tableName, TABLES_TO_BE_FILTERED.get(tableName.toUpperCase())); + } catch (Exception e) { + LOG.error("Failure exporting table {}", tableName, e); + } + } + } catch (SQLException e) { + LOG.error("While exporting database content", e); + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + LOG.error("While closing tables result set", e); + } + } + + DataSourceUtils.releaseConnection(conn, dataSource); + if (conn != null) { + try { + if (!conn.isClosed()) { + conn.close(); + } + } catch (SQLException e) { + LOG.error("While releasing connection", e); + } + } + } + + handler.endElement("", "", ROOT_ELEMENT); + handler.endDocument(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java new file mode 100644 index 0000000..086adfd --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java @@ -0,0 +1,94 @@ +/* + * 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.syncope.core.persistence.jpa.content; + +import java.io.IOException; +import java.io.InputStream; +import javax.annotation.Resource; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.apache.commons.io.IOUtils; +import org.apache.syncope.core.persistence.api.content.ContentLoader; +import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf; +import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * Initialize Database with default content if no data is present already. + */ +@Component +public class XMLContentLoader extends AbstractContentDealer implements ContentLoader { + + @Resource(name = "contentXML") + private ResourceWithFallbackLoader contentXML; + + @Override + public Integer getPriority() { + return 0; + } + + @Transactional + @Override + public void load() { + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + boolean existingData; + try { + existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + JPAConf.TABLE, Integer.class) > 0; + } catch (DataAccessException e) { + LOG.error("Could not access to table " + JPAConf.TABLE, e); + existingData = true; + } + + if (existingData) { + LOG.info("Data found in the database, leaving untouched"); + } else { + LOG.info("Empty database found, loading default content"); + + try { + loadDefaultContent(); + } catch (Exception e) { + LOG.error("While loading default content", e); + } + try { + createIndexes(); + createViews(); + } catch (IOException e) { + LOG.error("While creating indexes and views", e); + } + } + } + + private void loadDefaultContent() throws Exception { + SAXParserFactory factory = SAXParserFactory.newInstance(); + InputStream in = null; + try { + in = contentXML.getResource().getInputStream(); + + SAXParser parser = factory.newSAXParser(); + parser.parse(in, new ContentLoaderHandler(dataSource, ROOT_ELEMENT)); + LOG.debug("Default content successfully loaded"); + } finally { + IOUtils.closeQuietly(in); + } + } +}
